UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技
type: channel
link: https://blog.uwa4d.com/
description: UWA博客，UWA旗下官方博客。针对游戏及VR应用性能优化等内容记录、交流，以及案例分享。博客主要分为：厚积薄发、万象更新、博观约取、充电一刻、博物纳新等几个模块。
items: 卡顿帧自己划，Shader看编译，Overdraw自动采：这次把决定权交还给项目
items: 小游戏内存预留了，为何还会扩容
items: GPM 2.0 WebGL 监测能力扩容｜覆盖 Unity/Cocos/LayaAir 多引擎微信 & 抖音小游戏
items: 小游戏RenderTexture内存为何偏高
items: 卡顿和发热，未必是性能不够，也可能是分档配错了画质
items: 性能数据跟着问题走：2026年，你的AI也该懂怎么查Unity性能瓶颈了
items: 对象销毁了，为什么材质还留在内存里
items: 流式加载后，为什么GPU仍在裁剪大量三角形
items: 内存数据不再逐页翻！GOT Online开启“精准降本增效”模式
items: 动画示例项目旋转浅析 - GASP Rotation

卡顿帧自己划，Shader看编译，Overdraw自动采：这次把决定权交还给项目
type: item
date: 2026-09-02T05:05:00+03:00
description: 项目快收口时，经常会碰到这种要求：“这一轮标准再收紧一点，原来不看的那批帧也拉出来。” 问题也随之而来：项目已经换线了，工具还守着原来的默认阈值。那批需要继续排查的帧，在报告里看着却“挺正常”，测试同学只能自己再筛一遍。 默认规则当然有用，但真查进项目里，很快就会发现，同一把尺子很难从头用到尾。前期抓大放小，后期标准越压越紧，一些关键战斗、固定玩法和主城场景也可能有自己的性能目标。哪些帧要继续往下查，最终得看项目自己的要求。 卡顿帧自己划：把“刻度尺”交还给项目 这次，GOT Online把卡顿阈值开放出来了。阈值调整后，卡顿曲线、卡顿点和相关统计会按照新的标准重新计算。哪些帧进入本轮重点排查范围，由项目自己决定。 在同一浏览器标签页和同一份数据里继续分析时，自定义阈值和降噪状态会保留；刷新页面或切换其他数据后，再恢复默认。看起来只是改了一条线，但真正做性能分析时，哪批帧会先被看见，本身就会影响后面的排查起点。 非主线程打点：把“暗中吃时间”的嫌疑人拉出来 有些性能问题不会爆出明显尖峰。比如Lua GC、资源加载，或者拆到后台执行的逻辑，可能每帧只稳定占掉几毫秒，但整段流程跑下来，一直在吃CPU预算。 现在可以通过SDK API给关心的代码段打点，单独观察峰值和全流程平均耗时，判断它是偶发抬高，还是长期处在高位。 想盯Lua GC，就给Lua GC打点；怀疑资源加载，就把对应代码段标出来。先把怀疑对象拉出来，比在一堆线程里找重点更直接。 Shader日志直达：打破“只给函数名”的排查黑盒 报告里出现Shader.CreateGPUProgram大尖峰，只能说明这里发生了Shader编译，但还不知道涉及哪些Shader和编译记录。 以前分析到这里，经常得再去找设备日志和工程配置。现在可以直接采集并下载对应的Shader编译日志，目前仅支持Android包。 拿到日志后，可以结合编译记录继续确认当时涉及哪些Shader，为后续检查预热、变体管理和运行时触发路径提供线索。 Overdraw自动采集：不再靠测试同学“拼手速” 以前抓相机Overdraw，需要手动点击Capture Overdraw。碰到快速跑图、战斗或镜头快速变化，想看的画面很容易错过，有时只能重跑流程。现在可以提前配置相机Overdraw自动采集。 测试流程照常跑，系统按配置完成采集，减少对人工点击时机的依赖，也更不容易错过目标画面。 区间框选与有效均值：少进几次Excel 资源管理页面板新增资源总值，方便直接对比版本间的资源规模。有效帧均值只统计存在有效数据的帧，更接近资源实际出现期间的平均水平。 自定义面板支持直接框选时间区间，函数、资源和相关统计会按照选中区间重新计算。 以前可能要导CSV、进Excel、筛区间，现在很多时候框一下就能直接看结果。 让工具跟上项目自己的排查思路 真实的性能优化，本来就不是照着固定路线往下走。项目阶段变了、关注对象变了，手里的“尺子”也得跟着变。 卡顿帧自己划，线程自己标，Shader顺着日志追，Overdraw交给系统采，区间框到哪里，数据就算到哪里。工具少卡一下，排查思路就能更顺地接下去。 最后说两句： 我们深知，在项目期引入或尝试一个新工具是有决策成本的。 工具的价值，不仅在于它能算得多快，更在于它能不能真的融入团队的日常流转中，帮大家准时下班。 但如果它能每天帮你省下半小时的查Bug时间，这笔账就绝对划算。为了让大家能毫无负担地验证这波“AI+性能优化”的疗效，我们为大家准备了专属福利： 关于UWA UWA是一家创业十年的高新技术企业，作为游戏行业的深耕者，UWA始终专注于为使用Unity、Unreal引擎的开发者提供丰富的优化产品，帮助开发者高效解决开发问题、定位性能瓶颈、提供解决方案，已支持超过一万款游戏项目。还打造了技术博客、问答、学堂等社区产品，为开发者提供便利和高效的支持。线上培训和线下教育的新业务，满足行业对人才培育的需求。

小游戏内存预留了，为何还会扩容
type: item
date: 2026-09-01T05:20:00+03:00
description: 1）预留Heap为何还会扩容 2）闲置Camera为何还有Culling 这是第491篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：793972859 本次推送的实战案例来自于使用UWA服务的项目的真实且典型的问题。UWA将关键线索、定位路径与处理建议整理成了可复用的案例笔记，便于大家快速对照、排查自身项目中的同类问题。 实战案例 Q：小游戏Total Heap预留近500MB，为什么还会继续扩容？ A：Total Heap只是预留空间，真正决定是否扩容的，是Dynamic Heap的实际使用量。 从UWA GOT Online报告中可以看到，Total Heap初始约为496MB，运行后很快触及上限，随后扩到600多MB，后面又进一步扩到800多MB。说明并不是预留没有生效，而是Dynamic Heap已经超过了最初的预留范围。 这里还要特别关注扩容瞬间的内存压力。小游戏Heap扩容过程中，原有内存可能会先被复制，短时间同时存在新旧两部分内存。例如原本已经接近500MB，扩容阶段的瞬时占用可能接近1GB，对内存限制更严格的iOS设备风险更高。报告后期Dynamic Heap已经达到700多MB，继续拆分后大致包括： Native Heap：400多MB Mono：约150MB Lua或其他第三方插件相关内存：100多MB 所以这里不能只靠提高Total Heap初始值解决。一方面要根据完整运行周期的实际水位设置合理的预留空间，另一方面还要继续降低Dynamic Heap本身的占用。 Native Heap可以继续结合引擎及资源内存排查；Mono重点关注是否持续上涨；第三方插件则可以通过开关插件做对照测试，确认具体的内存贡献。同时，Total Heap也不是设得越大越好。初始值过高，同样会增加低端设备启动阶段的内存压力。 实战案例 Q：Camera没有实际参与画面渲染，为什么Culling耗时还在？ A：只要Camera仍处于启用状态，即使当前画面并不需要它，Culling等渲染准备工作仍可能继续产生CPU开销。 UWA GOT Online报告中Camera.Render的调用次数持续在10次左右。检查发现，场景虽然存在多个Camera，但部分当前不需要使用的Camera并没有Disable；与此同时，Culling在渲染模块中的耗时占比约为40%。 Culling需要根据Camera视角筛选后续可能参与渲染的对象，所以画面里没有看到这个Camera的内容，不等于这个Camera已经没有开销。角色预览、礼包展示、3D UI以及RenderTexture等功能都可能创建额外Camera。如果界面关闭后只是隐藏内容，却没有同步关闭Camera，这部分开销仍可能保留下来。 小游戏报告中的情况更加明显，部分区间Camera数量甚至达到40个左右，对应区间的渲染耗时也有明显上升。 排查时重点做三件事： 对比Camera.Render调用次数和当前画面真正需要的Camera数量； 检查UI、角色预览、RenderTexture等临时Camera是否在使用结束后及时Disable； 对必须保留的Camera，再检查Culling Mask是否包含了不需要处理的Layer。 处理后重新观察Camera.Render次数和Culling耗时是否下降，就能判断额外Camera是否确实贡献了这部分开销。 无论是社区里开发者们的互助讨论，还是AI基于知识沉淀的快速反馈，核心都是为了让每一个技术难题都有解、每一次踩坑都有回响。希望这些从真实开发场景中提炼的经验，能直接帮你解决当下的技术卡点，也让你在遇到同类问题时，能更高效地找到破局方向。 封面图来源于网络 今天的分享就到这里。生有涯而知无涯，在漫漫的开发周期中，我们遇到的问题只是冰山一角，UWA社区愿伴你同行，一起探索分享。欢迎更多的开发者加入UWA社区。 UWA官网：www.uwa4d.com UWA社区：community.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859

GPM 2.0 WebGL 监测能力扩容｜覆盖 Unity/Cocos/LayaAir 多引擎微信 & 抖音小游戏
type: item
date: 2026-08-26T05:51:00+03:00
description: 小游戏赛道蓬勃发展，除Unity之外，大量商业小游戏项目基于Cocos、LayaAir进行开发。 WebGL环境受浏览器虚拟机、单线程内存模型约束，线上版本普遍会遇到：偶发卡顿、内存持续上涨、GC抖动、低端机型闪退，大量问题线下模拟器难以复现，只能依靠玩家反馈被动救火。 GPM 2.0此前已经为Unity引擎开发的小游戏/WebGL上线了完整的专属线上监测体系，打通小游戏线上性能黑盒。本次迭代，扩展了SDK引擎适配范围，将这套线上性能监测能力，完整开放给Cocos、LayaAir引擎项目。至此GPM 2.0 WebGL监测可同时覆盖Unity、Cocos、LayaAir三大主流引擎的微信、抖音小游戏/WebGL项目，让更多小游戏团队可以享用同一套线上真实玩家性能分析能力。 ▘▖小游戏共性痛点：本地测试表现良好，线上却频出问题 无论使用Unity、Cocos还是LayaAir开发WebGL小游戏，都会面临共通的技术困境： 1.本地环境不等于真实玩家手机环境 编辑器、PC浏览器测试流畅，但移动端浏览器内核、内存限制、iOS非JIT机制会放大各类性能缺陷，很多问题只在线上真实设备触发。 2.内存问题隐蔽难复现 Cocos节点销毁不彻底、LayaAir资源缓存残留、JS对象频繁创建，会带来渐进式内存上涨。不会直接抛出崩溃报错，随着游戏时长累积逐步卡顿、被系统杀进程，线下很难复现完整长会话。 3.卡顿根因难以区分 脚本逻辑阻塞、GC抖动、渲染过载、资源加载混杂在一起，玩家只反馈“玩起来卡”，缺少数据定位到底哪一部分导致问题。 4.偶发BUG复现成本极高 部分卡顿、闪退仅出现在特定机型、特定操作序列，QA很难复现，问题长期悬置，持续带来玩家流失。 5.过去Cocos、LayaAir小游戏缺少专业线上监测工具，大多依靠打印日志与客服工单，数据碎片化，很难做版本回归、机型分层分析。 现在，GPM 2.0的整套WebGL线上分析能力，平台分析指标、回放逻辑、告警逻辑等功能扩展支持Cocos、LayaAir引擎项目。 ▘▖GPM 2.0 WebGL监测能力总览 整套能力为WebGL浏览器环境定制，不是通用性能工具简单兼容；SDK采集开销可控，画面截帧功能默认关闭，满足微信、抖音小游戏平台审核上线规范。 1.全维度线上性能时序指标采集 持续采集真实玩家会话FPS、帧耗时、帧率抖动、网络延迟、加载耗时，生成时序趋势曲线。 可以捕捉本地测试容易忽略的瞬时性能尖峰、间歇帧率抖动；支持按版本、渠道、机型、游戏场景聚合筛选，看清不同群体玩家真实线上体验，不被开发机的良好表现误导。 包含性能数据&截帧的异常对话报告 2.内存趋势追踪，定位内存泄漏问题 在运行环境支持的情况下，Unity、Cocos和LayaAir的WebGL项目均可采集WASM Heap、JS Heap以及二者组合得到的近似WebGL Heap指标。其中，JS Heap是否可用取决于浏览器或小游戏运行环境是否开放相关能力。 通过内存时序曲线，研发可以直观观察进入哪类场景、执行哪一类交互之后内存持续走高，快速定位资源残留、对象频繁创建等泄漏根源，排查渐进式闪退问题。 小游戏项目内存数据及趋势图 3.卡顿帧堆栈溯源+版本性能基线对比 发生帧率暴跌或卡顿事件时，捕获对应调用堆栈信息，定位耗时代码逻辑、循环执行或资源加载等问题。 不用反复复现玩家故障，优化需求直接落地对应业务模块。同时支持新旧版本、活动前后横向基线对比，识别迭代引入的帧率下滑、内存上涨等性能劣化，明确调优优先级。 单个玩家一次对话中发生的卡顿帧堆栈信息 玩家全局卡顿汇总批量分析 新旧版本性能数据对比 4.玩家故障现场回溯，解决线上难以复现难题 a.异常瞬间自动截帧：卡顿、帧率异常发生时留存游戏画面，直观看到故障时刻场景、UI、特效状态，不再只依赖玩家文字描述。 ⚠️ 提示：小游戏平台会受性能开销约束，截帧功能默认关闭，项目需要结合自身性能实测手动开启。 b.全链路玩家操作轨迹回放：记录玩家点击、滑动、场景跳转等交互行为，与性能时序曲线联动，复现完整会话，闭环偶发线上客诉。 在线玩家数据实时看板 玩家行为&性能数据&自定义事件一览 c.多维度定向筛选：支持渠道、机型档次、游戏场景、付费玩家分组过滤，可单独锁定低配机型、特定渠道独有的性能缺陷，针对性完成适配与资源轻量化。 5.覆盖小游戏完整研发运营生命周期 能力贯穿项目：测试验收 → 版本上线 → 活动迭代 → 长线运营。 ✔ 事前测试验收：批量收集多机型、浏览器环境真实性能，提前识别负载超标、内存风险，上线前完成优化。 ✔ 事中版本上线监控：全渠道感知性能波动，识别不同渠道、机型玩家体验差异。 ✔ 活动迭代保障：监控新副本、新特效上线瞬时负载，定位活动专属性能BUG。 ✔ 事后复盘沉淀…

小游戏RenderTexture内存为何偏高
type: item
date: 2026-08-25T05:13:00+03:00
description: 1）小游戏RT内存为何偏高 2）Physics耗时为何居高不下 这是第490篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：793972859 本次推送的实战案例来自于使用UWA服务的项目的真实且典型的问题。UWA将关键线索、定位路径与处理建议整理成了可复用的案例笔记，便于大家快速对照、排查自身项目中的同类问题。 实战案例 Q：同一套项目资源，APP侧RenderTexture占用只有30MB左右，但小游戏侧却达到130MB左右，为什么会出现这么大的差异？ A：排查后定位到两个明显的配置问题：小游戏侧3D渲染分辨率没有按预期缩小，同时Depth Buffer仍然使用32位格式。这两项都会增加RenderTexture相关的内存压力。 小游戏和APP端虽然运行的是同一套项目，但不同平台实际创建出来的RenderTexture配置可能并不一致。尤其是渲染分辨率、Depth格式以及MSAA配置，一旦平台侧实际生效情况不同，最终内存占用就会产生明显差异。排查时可以重点关注： 3D渲染分辨率没有正确缩小。 小游戏侧实际渲染分辨率较大，说明原有的降分辨率策略没有按预期生效。RenderTexture内存和宽高直接相关，如果3D场景仍然按照设备较高的原始分辨率渲染，Color和Depth相关RT都会随之增大。 APP端原本可以通过分辨率设置控制渲染尺寸，但到了小游戏环境，需要重新检查对应接口是否生效。对于URP项目，可以通过renderScale控制3D场景实际渲染分辨率，最终再放大到屏幕，而UI仍保持全分辨率显示。 Depth Buffer仍然使用32位格式。 小游戏侧当前使用的是32位Depth，而移动端原有配置使用24位。需要检查平台相关设置，将小游戏/WebGL纳入对应的Depth格式配置，减少这部分额外的内存占用。 确认MSAA配置。 当前RenderTexture配置中可以看到MSAA为2。MSAA会增加Color Buffer和Depth Buffer的存储开销，尤其是在RT分辨率较高时，需要保存更多采样数据，会进一步放大内存占用。排查RenderTexture内存差异时，需要确认小游戏侧最终生效的MSAA等级，避免平台配置差异导致额外的RT开销。 实战案例 Q：项目已经针对物理碰撞制作了简化模型，但低端机上Physics耗时仍然达到二三十毫秒。碰撞模型已经简化，为什么物理压力还是很高？ A：碰撞模型复杂度只是影响Physics耗时的一部分。如果Collider已经进行了简化，但Physics耗时仍然较高，还需要继续关注场景中同时参与模拟的动态对象数量，以及这些对象之间产生的碰撞关系。 从GOT Online报告中数据变化来看，随着场景中的物件减少，Physics耗时也同步下降，同时Overlaps数量明显降低。当前场景中的Overlaps已经达到几千级，说明物理系统需要维护大量潜在碰撞关系。排查时可以重点关注以下几个方向： 确认Physics耗时是否和碰撞关系规模相关。 可以减少部分动态物体参与碰撞，再观察Overlaps数量和Physics耗时是否同步下降。如果两者变化趋势一致，说明主要压力可能来自大量碰撞关系，而不是单个Collider复杂度。 检查动态Rigidbody和Mesh Collider组合。 场景中存在大量带Rigidbody的动态对象，其中部分使用Mesh Collider。对于动态非Kinematic Rigidbody，Mesh Collider需要使用Convex。形状允许的情况下，可以继续对比Box、Sphere、Capsule或者Compound Collider的实际效果。不过碰撞体替换最终仍需要结合项目实际测试结果，不能简单认为基础Collider一定更优。 减少无效碰撞检测。 如果部分对象之间没有实际碰撞需求，可以通过Layer Collision Matrix关闭对应Layer之间的Collision，减少不必要的碰撞组合。调整后可以继续观察Overlaps数量和Physics耗时变化。 检查物理模拟频率。 Unity默认按照Fixed Timestep执行物理模拟。当低端设备出现掉帧时，一个渲染帧内可能需要补做多次物理模拟，从而进一步增加Physics耗时。可以尝试调整Fixed Timestep，例如从0.02调整到0.03，对比Physics耗时以及实际物理表现。 Unity 2022以后，也可以测试不同Physics Simulation Mode带来的影响，例如切换到Update驱动，观察减少单帧多次物理模拟后能带来多少收益。不过…

卡顿和发热，未必是性能不够，也可能是分档配错了画质
type: item
date: 2026-08-21T10:20:00+03:00
description: 今天小Q聊聊GPM的「设备体验雷达」。把“设备分档”这件老大难，从拍脑袋变成看得见。 读完本文你可以：看懂你的项目真实设备画像、定位画质‑设备错配问题、科学调校设备分档、开启小Q自动巡检。 小Q先从一个容易被忽略的地方说起：在“设备”这件事上，平均帧率是个和平主义者 —— 它把所有人的痛苦平摊，然后告诉你大家都还行。 你的大盘均帧看着挺体面。可那是旗舰机、中端机和一批老机器加权平均出来的。那批在二十几帧上挣扎的玩家不会出现在这个数字里，他们只会出现在退款和差评里。 但这篇文章真正想说的，不是“有人卡”。是他们里面有相当一部分，本来可以不卡。 一件每个团队都在做、但基本靠猜的事 你的游戏里一定有一套画质分档 —— 低、中、高，或者更细：开不开后处理、要不要动态阴影、渲染分辨率给多少、锁不锁帧。这套档位怎么发到玩家手上？大多数团队的答案是：一份机型白名单，加一套按GPU型号或公开跑分写死的规则，可能还是两年前定的，改一次要排期。 这套规则一旦和真实玩家对不上，后果不是某张报表不好看，是具体的人在具体的机器上卡顿、发烫、掉电、闪退：老机器被判高了，默认给了它扛不住的画质，于是它烫、它掉帧、它闪退；好机器被判低了，玩家花钱买的性能，你没让他用上。 这是设备这件事上最贵的一类问题，也是最容易漏掉的一类 —— 因为它不报错。崩溃有堆栈，Error有日志，画质配错了不抛任何异常，只留下一条慢慢往下走的留存曲线。等你从工单里看出苗头，往往已经过了两个版本。 过去做设备适配，我们往往缺少三样关键信息： 不知道自己项目玩家真实的硬件构成，不是行业公开市场份额，而是属于这款产品的真实设备分布； 无法验证自研分档规则，在自家游戏下，各档位实际体验是否拉开合理差距； 看不清画质档位下发之后，每一档设备真实运行的画质，以及错配机型的实际体验。 这三样，过去只能靠抽样机测、靠客服工单、靠论坛里那句“我这手机烫得能煎蛋”。 GPM的「设备体验雷达」就是来补这三样的。它不需要你埋点，也不需要额外配置 —— 你现在的上报数据直接就能看。 下面我按你实际会撞上问题的顺序讲，不是按菜单顺序 ，文中截图都取自产品内置的演示数据、不是真实上报。 平均帧率是个和平主义者：它把所有人的痛苦平摊，然后告诉你大家都还行。 第一件事：你的玩家，实际在用什么设备？ 你大概能说出行业里最热门的十款机型。但那和你的玩家是两回事 —— 一个二次元游戏和一个SLG，玩家手里的机器可以完全不是一批。 雷达的第一页叫「设备结构与风险概览」，它上半屏就是「设备结构概览」。这一屏先不给你任何结论，只给你一张户口本：多少台设备、多少次会话，你的分档规则把这些人切成了什么样，以及机型、SoC、GPU三张热度榜。如果你在项目里配了自定义分档，它会把系统默认分档和你自己那套并排摆着 —— 同一批玩家，两把尺子量出来什么样，一眼可比。 设备结构概览 这里你只需要盯住一个格子：Unknown。它装的是GPM目前认不出来的设备。 为什么会有认不出来的呢？主要是三种： 太新：刚上市的机器，设备库还没来得及收录； 太偏：确实小众的硬件，Android学习机、冷门平板，甚至Android手表，这类东西本来就不在主流收录范围里； 假的：模拟器改过的硬件信息，报上来的那颗“GPU”很可能压根不存在。 这三种情况该做的事完全不同：第一种等收录就行，第二种你得决定要不要为它花适配成本，第三种你根本不该把它算进玩家设备分布里。所以我们既不猜，也不硬塞进某一档，而是如实标成Unknown，再给你一个能查清楚的地方 —— 「设备信息订正」页会逐台列出这些到底是什么设备、属于上面哪一类，能补的你当场补，补完全站的分档口径跟着一起对。 为什么值得你专门看这一格：很多人瞄一眼占比不高就跳过了，但同一页往下滚到「体验差异与风险对比」你会发现，这批“没归类”的机器，实测帧率往往比你最低那一档还低。它们不是无关紧要的一小撮，只是没进到任何一档里，所以在任何一档的均值里你都看不见它们。这个数字一高，后面所有分档结论都要打折 —— 发红了请先去订正，别急着看诊断。 分不清的设备，分不出的结论。 除此之外，这一屏只是个起点：它告诉你人是怎么分布的，但分布本身说明不了你分得对不对、配得对不对。这两个答案，一个就在同一页往下滚的「体验差异与风险对比」里，一个在「分档诊断」页。我先讲更要紧的那个。 第二件事，也是最要紧的一件：你配的画质，配到对的人手上了吗 这是整套雷达里我最想让你先打开的一块 —— 「分档诊断」页上的「设备分档 × 画质匹配」。它最直接对应开头那个问题：为什么玩家会卡、会烫，以及那批本来不该卡的人在哪儿。 它做的事说穿了很简单：把每台设备属于哪一档和这台设备实际跑着哪个画质这两件事叉在一起看，然后回答三个问题 —— 配对了多少、配高了多…

性能数据跟着问题走：2026年，你的AI也该懂怎么查Unity性能瓶颈了
type: item
date: 2026-08-19T05:30:00+03:00
description: 用AI查性能，第一问一般过得去。报告刚跑完，丢进Cursor问“这版为什么掉帧”，它多少能说两句。 下一句就费劲了。 你想知道卡在哪几帧、哪个函数，这些数常常不在对话里。于是停下来，切回报告翻曲线、搜函数、把帧号抄出来，再切回Cursor接着聊。换Codex或Claude Code，也是同一套动作。 来回几趟，刚才想的那点东西就散了。工作量不大，就是烦。 于是，我们把UWA已经开放的查询接进了MCP。你问到哪，它去报告里取哪一段，少切几次。 前两天小编手头有一份现成的GOT Online报告。测试同学在群里说：中间有一段卡得厉害。正好编辑器还开着，小编我也懒得对曲线，直接在Cursor里问了。 先问：主线程有没有明显慢帧，慢在哪几帧。 Cursor回过来是帧号：第103帧，主线程大约1538ms....以前这会儿就得切回去对时间轴，把帧号记在备忘录里，现在数字已经在对话里了。 以前问到这，我多半会说「等一下，我去把103的堆栈翻出来」。这回堆栈就在下一句。 我又问：其他慢帧呢，像不像同一类？ 对比之下，很多人是把报告截图，或者把概述贴给AI。第一句够用，再问下去，下一张图不在上下文里，它只能猜，或者等你再翻。接上MCP之后，问慢帧就去取帧号，问某一帧就去取这一帧的堆栈，觉得像个模式，再把旁边几帧拉过来。还是那份GOT Online数据，中间少了几次自己动手。 CI、看板、准出卡继续走 OpenAPI，没必要重做。这次Overview补了函数曲线、每帧耗时，也能取指定帧的堆栈，往下挖方便一点。MCP把这些查询接到对话里，给那种下一步还没想好的排查用。 已经在Cursor、Claude Code或Codex里看代码的，用上周那份GOT Online报告就能试。可以先问主线程有没有明显慢帧，帧号是多少；再问最慢那一帧时间花在哪、同帧还叠了什么。如果还像同一类，让它把其他慢帧也拉出来对照。 刚改完战斗或者UI，提测前不踏实，问一句也行：我刚动过的这几个函数，这次测试里耗时有没有变？它手头没有，会自己再取。 固定流程用OpenAPI 动态排查更适合MCP 对于已经跑稳的工业化管线（如固定拉指标、跑CI、维护性能看板），场景、CPU/GPU、逐帧数据等指标，直接通过UWA OpenAPI接进原有流程即可，稳定高效。 而MCP真正发力的，是那些“下一步还没定”的疑难杂症动态排查。 先看FPS，发现集中在某块地图，再拿场景数据；GPU没变化，注意力立刻转给CPU；范围缩小到异常帧，再深挖函数调用。数据还是UWA的数据，只是中间彻底省去了你接接口、翻报告、整理完再丢回AI的低效体力活。 最后说两句： 我们深知，在项目期引入或尝试一个新工具是有决策成本的。 工具的价值，不仅在于它能算得多快，更在于它能不能真的融入团队的日常流转中，帮大家准时下班。 但如果它能每天帮你省下半小时的查Bug时间，这笔账就绝对划算。为了让大家能毫无负担地验证这波“AI+性能优化”的疗效，我们为大家准备了专属福利： 关于UWA UWA是一家创业十年的高新技术企业，作为游戏行业的深耕者，UWA始终专注于为使用Unity、Unreal引擎的开发者提供丰富的优化产品，帮助开发者高效解决开发问题、定位性能瓶颈、提供解决方案，已支持超过一万款游戏项目。还打造了技术博客、问答、学堂等社区产品，为开发者提供便利和高效的支持。线上培训和线下教育的新业务，满足行业对人才培育的需求。

对象销毁了，为什么材质还留在内存里
type: item
date: 2026-08-18T05:29:00+03:00
description: 1）Material Instance为什么持续增长 2）动态生成Mesh后，为什么Mono内存变高了 这是第489篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：793972859 本次推送的实战案例来自于使用UWA服务的项目的真实且典型的问题。UWA将关键线索、定位路径与处理建议整理成了可复用的案例笔记，便于大家快速对照、排查自身项目中的同类问题。 实战案例 Q：项目运行一段时间后，Material Instance数量持续增长，从开始的100多个增加到2000多个，这是什么原因？应该如何排查？ A：这种情况可以先排查运行过程中是否不断实例化了新的Material。报告中可以看到，某类技能材质（Instance）从最开始的100多个逐渐增加到2000多个，而且持续出现新的实例。这类现象通常需要结合技能、角色、特效对象的生命周期一起看，确认运行过程中是否不断产生新的Material Instance。 Unity中访问Renderer.material时，如果当前Renderer使用的是共享材质，Unity会为它实例化一份独立的Material。这里不只是调用SetColor、SetFloat等修改操作需要注意，仅仅访问Renderer.material本身，就可能触发实例化。如果只是读取或继续使用共享材质，可以检查是否应该使用Renderer.sharedMaterial。 真正容易被忽略的是材质和GameObject的生命周期并不是完全绑定的。通过Renderer.material等方式在运行时实例化出来的Material，不会因为对应GameObject被Destroy就自动完成资源释放，需要对这类动态材质单独管理。 比如技能释放时创建了临时特效对象，同时实例化了一份材质。技能结束后GameObject已经销毁，但这份Material没有被显式销毁，下一次释放技能又生成新的实例，长期运行后就可能看到Material Instance数量从几百一路涨到几千。未被使用的材质也可能在Resources.UnloadUnusedAssets()等资源清理过程中被回收，但不应该把它当成高频动态材质的主要生命周期管理方式。 排查时可以从持续增长的材质名称入手，再对应技能释放、角色生成、特效播放等操作做复现。如果每执行一次操作，某类Material Instance数量都会增加，而对应对象销毁后实例仍然保留，就需要继续检查这条材质创建和销毁链路。 优化时可以重点关注两个方向： 减少不必要的Material Instance创建。 检查是否存在只为了读取材质却访问Renderer.material的情况；如果只是修改颜色、Vector等每个Renderer不同的属性，也可以评估MaterialPropertyBlock是否适用，减少独立Material实例。需要切换Shader或Shader Keyword时，则不能简单用MPB替代。 显式管理动态材质生命周期。 如果确实需要实例化Material，需要保留对应引用，并在对象生命周期结束时显式Destroy。对于高频创建的技能、角色和特效，也可以进一步检查是否能够复用材质，而不是不断创建新的实例。 实战案例 Q：项目地图区域原本直接使用MeshRenderer，但动态加载、卸载时会有卡顿，后来改为在脚本中保存顶点等数据，运行时再动态生成Mesh。UWA GOT Online报告显示Mono内存占用较高，如何判断是否和这部分数据有关？ A：可以先通过Memory Profiler确认Mono堆中的主要占用。如果其中存在大量顶点、矩阵等Mesh相关数据，再结合引用关系查看这些数据是否由地图区域相关脚本对象持有，就能进一步判断Mono占用是否和这套动态Mesh实现有关。 这里需要关注的并不是“动态生成Mesh”本身，而是为了生成Mesh，脚本侧长期保存了多少网格数据。例如C#侧保存了大量Vector3[]、索引数组或矩阵数据，这些内容会占用Managed Heap，也就是这里看到的Mono内存。随后再把这些顶点、索引数据提交给Mesh，Mesh自身还需要在Native侧维护对应的网格数据。 因此，如果Mesh已经生成，而C#侧的原始顶点、索引等数据仍然长期保留，就可能出现同一批网格信息同时占用Managed和Native两侧内存的情况。这里不能简单理解为固定的“双倍内存”，但确实需要同时关注两边的数据占用，而不能只看Mono。 排查时可以重点看： 确认Mono中的Mesh相关数据占了多少。 查看顶点数组、索引、矩阵等数据的数量和实际占用，再通过…

流式加载后，为什么GPU仍在裁剪大量三角形
type: item
date: 2026-08-12T05:09:00+03:00
description: 1）流式加载后，为什么GPU仍在裁剪大量三角形 2）开启级联阴影后，三角形数量为什么明显增加 这是第488篇UWA技术知识分享的推送，精选了UWA社区的热门话题，涵盖了UWA问答、社区帖子等技术知识点，助力大家更全面地掌握和学习。 UWA社区主页：community.uwa4d.com UWA QQ群：793972859 本次推送的实战案例来自于使用UWA服务的项目的真实且典型的问题。UWA将关键线索、定位路径与处理建议整理成了可复用的案例笔记，便于大家快速对照、排查自身项目中的同类问题。 实战案例 Q1：大地图已经做了流式加载，只加载角色附近区域，但GPU里仍有大量三角形被裁剪。为什么还会出现这种情况？ A：可以先看UWA GOT Online报告中GPU Input Primitive的数据，继续拆分Culled Primitives的具体构成。 以报告中第830帧为例，Culled Primitives约95.8万，其中Facing & XY Plane Culling Primitives约43.2万，Z Plane Culling Primitives约21万，Coverage Culling Primitives约31.6万。 Facing & XY Plane Culling里包含背面剔除，这本身属于正常的渲染流程，而且目前无法继续区分其中有多少来自背面剔除、多少来自XY方向超出范围，所以不能直接把这部分都当成无效开销。 Z Plane Culling可以优先检查场景里是否有覆盖范围比较大的Mesh。比如一块Mesh横跨较大的空间，其中一部分几何已经超出摄像机视锥的前后范围，但整块模型仍然被提交给GPU，这种情况下可以评估大块Mesh是否需要适当拆分。 Coverage Culling则可以重点检查LOD。如果模型已经离相机很远，但仍保持近距离时的高面数，三角形投射到屏幕后会非常小，其中一部分甚至覆盖不到有效采样点，最后被GPU裁掉。可以检查远距离LOD是否降得足够。 Q2：项目里的角色支持换装，如果给不同衣服都做LOD成本比较高，这种情况下角色LOD还需要做吗？ A：可以先确认角色对当前三角形数量的影响有多大，再决定是否值得做。比较简单的方式是在相同场景、相同视角下做一组开关测试，一组正常显示角色，一组把角色关闭，再对比Primitive相关数据。 角色关闭后三角形数量和裁剪数据明显下降，说明角色对当前几何压力的贡献较大，可以进一步评估角色LOD；数据变化不明显，则优先把精力放在场景模型上，继续检查大块Mesh和场景LOD。 实战案例 Q：高画质开启级联阴影后，三角形数量从几十万涨到100万以上，这部分增长和级联阴影有关吗？ A：有关系。级联阴影会让部分物体重复参与阴影绘制，同一个物体除了正常渲染，还可能需要参与额外的阴影绘制，所以GPU需要处理的几何量也会增加。 高画质下Triangle数量 中画质下Triangle数量 从GOT Online报告数据来看，两档画质下的几何量差异比较明显。中画质下大部分场景维持在几十万，峰值约62.1万；高画质下则多次接近或超过100万，峰值约130.6万。 不过，高画质下可能还同时调整了其他渲染配置，所以不能把这部分增长全部归到级联阴影上。可以固定场景和摄像机视角，只调整级联阴影相关配置，再对比Triangle或Input Primitive的变化。 中画质GPU Fragment Shaded 除了三角形数量，也可以结合GPU Fragment Shaded看GPU侧的压力。从报告中可以看到，Fragment shaded均值约332.2万，峰值约966.1万，说明除了几何量以外，还可以继续关注片元侧的处理量。 高画质下GPU压力增加时，不建议只看三角形数量。可以结合Triangle、Input Primitive和Fragment Shaded等数据一起判断。 无论是社区里开发者们的互助讨论，还是AI基于知识沉淀的快速反馈，核心都是为了让每一个技术难题都有解、每一次踩坑都有回响。希望这些从真实开发场景中提炼的经验，能直接帮你解决当下的技术卡点，也让你在遇到同类问题时，能更高效地找到破局方向。 封面图来源于网络 今天的分享就到这里。生有涯而知无涯，在漫漫的开发周期中，我们遇到的问题只是冰山一角，UWA社区愿伴你同行，一起探索分享。欢迎更多的开发者加入UWA社区。 UWA官网：www.uwa4d.com UWA社区：community.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859

内存数据不再逐页翻！GOT Online开启“精准降本增效”模式
type: item
date: 2026-08-06T09:36:00+03:00
description: 对很多项目组来说，“内存”永远是性能优化里避不开的硬骨头。但每次分析报告时，寻找各种内存指标、整理不同岗位的内存数据，往往耗费了大量的无用时间。GOT Online此次更新，主打的就是把核心内存数据集中呈现，并全面增强了对内存细分资源的定位能力。 除了针对内存分析的重磅升级，本次还同步上线了函数Top10耗时点和函数组数据一键导出等实用功能。 聚合常用指标：按需定制专属面板 做性能排查时，程序、美术、测试打开的是同一份报告，但关注点完全不同。哪怕都在美术团队，场景、角色、特效需要盯着的数据也差了十万八千里。 结果就是每次打开报告，都得重新翻页、找指标、做对照。数据明明都在，时间却花在了“去哪里找”上。好的性能工具，从不强求全员看同一份大表，而是让每个人打开报告的第一眼，都能直奔自己的“主战场”。 GOT Online本来就支持自定义模板，这次进一步把内存分析模块中的指标也放进了面板。以后经常看的内存数据，直接集中搬到自定义面板里，大家按自己的工作内容建立模板，搞场景的看场景，搞特效的看特效。关注的数据一眼就能拿到，不用再在大大小小的页签里绕圈子。 结合同步更新的场景性能表，还能进一步看清各个场景区间的细分指标。像 DrawCall 均值/峰值、不透明与半透明 DrawCall 分布等数据一目了然，甚至超标项还会直接高亮预警。看到哪个场景区间有问题，点击对应行的“查看场景数据”就能秒级跳转深挖，排查效率直接拉满。 深挖Unreal资源：三步锁定内存大户 自定义面板解决了“内存数据怎么看更快”的问题。但一旦发现内存异常飙升，接下来还是得回答那个最现实的问题：到底是哪类资源占得多？最后又落到了哪个具体的资产上？性能排查最怕凭空盲猜，缩短排查路径的本质，就是尽可能减少这种无效猜想的过程。 GOT Online之前已经支持Unity项目的资源内存分析，这次把这项能力也补齐给了Unreal项目。现在Unreal项目也可以直观查看资源内存趋势、数量变化和不同资源的占用分布。纹理、网格、动画、音频、材质、Shader、RenderTexture和粒子系统等，都能分类查。 以前看到内存涨了，大家第一反应只能是猜：“是不是纹理爆了？还是RenderTexture没释放？”现在可以先看类型分布，纹理占用明显抬高，就先查纹理；RenderTexture数量不对，就继续盯RenderTexture。 看清类型后，点进具体资源列表，资源名称、内存占用峰值、数量、生命周期直接展现。如果是纹理，还能结合尺寸、格式、Mipmap和Streaming等属性继续判断。这样排查路径就彻底顺了：先看内存怎么变 ➔ 再看是哪一类 ➔ 最后追到具体资源。报告不会替项目直接下结论，但至少不用对着一条上涨曲线干猜了。 标出耗时Top10：快速定位最慢帧 一条耗时曲线上可能有成千上万个数据点，真正值得关注的，通常只是少数几个卡顿峰值。以前排查偶发问题，沿着曲线来回翻，大部分时间看到的都是正常数据。但性能优化的黄金法则，永远是先干掉最显著的瓶颈。别把有限的精力浪费在那些平稳正常的帧上。 现在，只需点击按钮，就会直接在曲线上标出Top10最慢的点。哪些位置拖了后腿，一眼就能挑出来，再结合对应帧、线程和上下文去深挖。当然，Top10只是耗时最高的位置，不代表它一定就是卡顿根因。但它至少把范围缩小了。与其从头到尾逐帧找，不如先盯住这10个最可疑的位置，排查效率显然高得多。 导出一键完成：告别手动搬运数据 很多团队都会按照项目特点建立“函数组”，把长期关注的函数整理在一起，用来做版本复测、设备对比或问题回归。麻烦的是，报告一多，这些函数组和对应耗时数据也会散在不同地方。后面想做对比，或者交给其他同事继续分析，往往还得手动重新整理一遍。 性能优化本身就足够消耗脑力了，完全没必要再把时间消耗在重复的数据搬运上。GOT Online现在支持一键导出所有函数组以及对应耗时数据。导出结果既有整体汇总（总耗时均值、自身耗时均值、耗时占比等），也有组内每个函数的详细耗时和调用数据。 同时，这项数据也已经同步支持OpenAPI拉取。不仅可以手动导出Excel，还能直接接进团队内部的自动化平台或对比工具。版本复测时，把不同报告的导出结果拿来一比，或者用接口自动跑对比脚本就行，不用再傻傻地逐个函数组去抄数据了。 场景横向对比：一眼找出表现异常 长时间运行的测试报告里，往往穿插了多个场景。真正开始深挖之前，第一步通常不是直接查某个具体函数，而是先找出“哪个场景表现不太对”。 GOT Online针对Unity项目重做了场景概览页，把不同场景的关键指标（FPS、CPU、GPU、内存、耗电和温度）拉到一起横向对比。哪个场景FPS突然掉底，哪个场景内存数据异常，通过图表和列表一眼就能看出来。先把差异摆出来，告诉你哪…

动画示例项目旋转浅析 - GASP Rotation
type: item
date: 2026-08-05T05:01:00+03:00
description: 【USparkle专栏】如果你深怀绝技，爱“搞点研究”，乐于分享也博采众长，我们期待你的加入，让智慧的火花碰撞交织，让知识的传递生生不息！ 前言 UE：5.7.1 GASP：5.7 本文是以Mover版本角色来进行浅析GASP中旋转的实现，包括Strafe移动，AimOffset，TurnInPlace。 同时也会结合分析Lyra和ALS的一些实现方案。 1. Debug与基础RotationMode 1.1 Debug 为了更方便查看旋转相关的Debug信息，我们需要打开Widget中的Draw Shapes，就会看到下图这样很多的箭头，其中有意义的部分为： 圈内黑色大箭头：Root根骨骼朝向 圈外黑色小箭头：角色（碰撞体）朝向 亮粉色箭头：TargetOrientation旋转偏移前的目标朝向 暗粉色箭头：TargetOrientation+RotationOffset旋转偏移后的目标朝向 橙色箭头：MovementIntent，角色的期望运动方向 绿色弧线：当前MovementDirection移动朝向的范围 1.2 RotationMode 在GASP中，旋转模式分为OrientToMovement、Strafe和Aim，如果你是用过ALS的，那么它们是与VelocityDirection、LookingDirection和Aiming一一对应的。 OrientToMovement：角色将旋转至面向移动方向 Strafe：角色在移动时将大体面向瞄准方向旋转 Aim：角色将始终以最小偏移量精确面向控制器旋转方向，也算是Strafe模式 RotationMode主要是由玩家的按键输入以及游戏模式决定，在GASP中可以通过鼠标中间切换Strafe和Movement两种模式，并且可以按住右键进入Aiming模式。在常见的开放世界游戏中大多都是默认使用OrientToMovement模式，而当玩家拿起弓箭或者枪械瞄准时则会进入Strafe之中。 其中OrientToMovement比较简单，角色朝哪边移动就转向哪边即可，就不过多介绍。 2. Strafe基础 2.1 BlendSpace做法存在的问题 记得我最早接触Strafe移动还是在跟着一些UE4新手教程做战斗系统的时候，当做到了弓箭瞄准，或者类似只狼锁定目标时，就需要出现玩家始终面朝某个方向，却向着其他方向移动的情况。但是新手教程中的做法往往很简单，例如下图这种，用一个Direction来表示离面朝方向偏差多少角度，然后一个1D BlendTree混合。也有稍微好一点点的会使用2D BlendTree，使用LR/FB来进行混合。 1D因为不是环形的，在遇到从左后切换到右后时，需要经过-180度到180度把中间状态全都走一遍的情况，表现十分奇怪。而2D无论是四向在融合的地方都可能出现预料之外的表现。对于一些融合表现不好的地方可以选择补全八向动画。 若使用RootMotion动画，混合后会出现移速衰减问题，例如前后、左右单方向移动速度均为100，在往左前走的时候速度就只有50 √2 ，但是我们的期望肯定是斜向移动也是100，最简单的做法通过调整动画播放速度，来调整移动速度，但是会比较鬼畜。也可以考虑用程序补偿，缩放一下，或者直接用程序位移。 2.2 程序化多方向动画 二维的BlendTree也并不是要固定四个方向的动画，可以根据需要灵活调整为8向，10向都是OK的，GASP则是用到了四个动画F\B\LL\RL，但GASP并不是通过BlendTree混合出来的，使用BlendTree融合在没有动画的角度融合的角色往往会不尽人意，其使用的是OrientationWarping，同样是程序化修改在小范围内效果还是可以的。Lyra更是暴力地只用一个动画就OrientationWarping了360°出来。 OrientationWarping能使脚根据运动方向向不同方向移动。让下半身运动匹配移动方向，而上半身保持不变，以此实现向不同角度进行Strafe。他的实现逻辑是先旋转Root，再反向依次旋转Spine，例如下图中就是使用向正右方移动，但是被Warp了45度到了右前方。 2.3 腿部穿插 无论是BlendSpace还是OrientationWarping这些方法都无法解决脚步交叉的问题。而脚步打绕常出现于交叉脚的时候去往另一个Pose融合，但是切换过去的脚前后相反，直接融合过去就会穿插，比如下图本来是向右走的左脚在前，交叉时切回向后的右脚在前，腿就穿了。 为了解决这个问题，一个比较常见的做法就是分扇区，将前向和后向分别作为不同的BlendTree，在每个扇区中都让同一只脚保持在前方，同时保证同样播放进度时脚都是同一的前后位置，这样在扇区内Blend的时候就不会出现前腿要放到后方的…