UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 - 资源
本地资源检测新增UI界面｜更易用、更丝滑
UWA已经推出了本地资源检测服务，并受到大家积极回应。在与用户的沟通交流中，我们惊喜地发现已有开发者基于该功能的代码实现，制作了可视化的UI界面，相关同事可直接进行自定义规则的检测设置，进一步降低他们的使用门槛。 “本地资源检测工具是可以通过uwascan_ruleconfig.json来配置检测项的，对于程序员还好，但是如果是QA组或者非技术人员参与排查就不方便切换了。于是我自行制作了对应的设置界面来操作切换配置。” ——黄程 看到这波操作，UWA团队异口同声地感叹：对团队同事来说太友爱了！这样的队友请给我来一打！ 在此特别感谢黄程团队对UWA和“本地资源检测”的认可。 受黄程启发并沟通后，我们决定将这个组件开放，供大家下载使用。考虑到用户首次使用“本地资源检测”，一般都是需要进行规则配置的，那么相比于陌生且“死板”的配置文件，UI界面操作无疑是个更友好的解决方案。 说明：我们现在配置文件方案和UI界面方案是共存的，新老用户皆可兼容使用，并且在UI界面中不同模式的选项下方做了相应的文字说明。 使用流程 在UWA官网接入了新组件后，Unity引擎的Tools->UwaScan选项中多了个Settings的选项，点击Settings选项后，就可以呼出UI界面，如下图所示： 界面呼出后，左侧会显示5个检测选项。在【通用】选项中，可以进行“场景扫描模式”、“资源扫描模式”、“资源扫描路径列表”，“扫描忽略路径列表”等操作。 剩下4个选项对应4个插件的规则启用/禁止，UI界面上所展示的功能与uwascan_ruleconfig文件中的配置项完全一致，用户在UI界面中配置后，会对uwascan_ruleconfig文件进行写入操作，等同于用户进行了配置文件的操作。组件在执行的时候，仍然是读取配置文件中的规则进行执行，这个逻辑与原有逻辑相同，不发生改变。 该功能需要大家更新检测组件，可登录UWA官网，【本地资源检测】服务中创建项目，点击【相关下载】即可获取最新组件。 替换文件如下： 对于已经使用了UWA本地资源检测服务并做过配置自定义的小伙伴们，可直接更新UwaProjScan.dll即可，该更新会兼容用户已存的规则。 关于【UWA本地资源检测】 本地资源检测是UWA推出的、面向于静态资源的全量分析，可针对项目组制作的美术资源进行检测，结合大家自己设定的阈值，快速检测资源的不合理情况，帮助研发团队及时发现并修复。 该服务目前已经成为不少开发团队的打版必备流程：每天半夜自动检测出报告，便于研发或QA团队第二天能快速查看数据报告并做针对性的修缮，大幅度地提高了研发效率。快来联系UWA小助手微信（17502188376）申请免费试用吧！
本期聚集话题：Render.Mesh耗时剖析、PSS走势详解、合理优化RenderTexture、排查没有依赖的插件资源等，都是非常实用的技巧哦~ 这是第102篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间15分钟，认真读完必有收获。文末，我们的互动话题是，AssetBundle Diff Patch 方案是否可行？期待你的高见！ UWA 问答社区：answer.uwa4d.com UWA QQ群：793972859（仅限技术交流） 渲染 Q1：可否解释下不透明渲染中，BatchRenderer.Flush中的Render.Mesh代表什么意思，我看在我的报告中一直都很高。这个数据算正常吗？ UWA：这个问题正好可以解释一下Flush下的这些显示项含义。BatchRenderer.Flush其实就是引擎要对当前这一帧进行渲染时的CPU端开销。一般来说，都是先Batch Draw Call，然后就可以调用Ogl相关代码分批次将数据传输到GPU端进行渲染了。 这里根据项目的不同主要会出现三个显示项：Batch.DrawStatic、Batch.DrawDynamic和Render.Mesh。其中DrawStatic表示当前帧同通过Static Batching的Mesh的Draw Call统计耗时。相应的，DrawDynamic则为Dynamic Batching相关耗时。而Render.Mesh则为无法进行Draw Call Batching的统计耗时。 题主提供的信息中，可以看出是Render.Mesh的Draw Call为42，而CPU耗时为8.27ms，坦白说，对于42个Draw Call来说，该值属于偏高了。但具体原因，但这份表格是无法获悉到的。对此，UWA的建议如下： （1）题主需点击“Render.Mesh”查看其在整体测试中的CPU耗时走势，如果只是单一几帧出现零星高值，则不用过于担心，因为任何统计都不免出现“奇异值”； （2）但如果是普遍、持续的高耗时，那么就必须严肃对待了。可以通过报告中的图表查看出现高CPU耗时时的具体位置，然后有针对性地进行更为深入的分析，比如使用Unity Frame Debugger，重点查看到底会有哪些无法Batch的Draw Call，是否合理等； （3）通过第（2）步，你应该可以了解了一些无法进行Batch的模型，然后可以进行一些二分法来逐步定位到底哪些模型对其耗时影响最大，直到排查到问题为止。 当然，还有一个高效的方法，就是把项目抠一个可复现问题的Sample出来，然后发给我们。我们每天都在帮助深度客户来解决问题，一些典型问题我们会以专栏的方式放出来，具体可以看求知探新。 该回答由UWA提供，欢迎大家转至社区进行进一步交流： https://answer.uwa4d.com/question/5aa15dbfd35eb22c10a0a372 资源管理 Q2：我们用的是Unity 2017.3，游戏工程删除Resources文件夹和所有Scene后出的空包非常大，检查发现使用的插件包含比较多的图片导致。但是那些资源没有地方引用，怎么会打进包里呢？如果全部删除的话在开发的时候不方便，所以请问有没有办法在出包是剔除没有用的资源？ 配图： 题主可以自己修改下插件，把资源放到”Editor Default Resources”或者”Editor/Resources”下，不要直接放Resources下，反正根据打包日志慢慢把这些插件的清理干净就好，体力活。 PS. 在Unity 5.4之前(大概是这个版本，具体要查Changelog) ，Editor下的Resources也会被打包进来的，后来就修掉了。 感谢UWA问答社区 @钱康来 提供了回答，欢迎大家转至社区进行进一步交流： https://answer.uwa4d.com/question/5a97b0330b827e2c0bfdd06b 资源管理 Q3：对于RenderTexture的优化一直比较迷茫，貌似和分辨率和AA关系比较大，上图是相关的设置图，我想请教下。 1）这个分辨率的设定一般怎么比较合理？1440×2560是不是有点高了？ 2）AA的设置一般是None吧？看大家说在移动设备上一般不需要开启这个效果，是吗？ 3）Color Format一般选什么格式呢？ARGB32的比较高清，那是否也会占据大量的内存？ 4）这个参数设置图中是否还会有其他因素也造成RT较高？ 下图是我们的资源详情图，希望能给些分析建议，谢谢！ 1）RT分辨率的设置取决于这张RT是做什么使用的。一般RT的大小为屏幕尺寸大小，也就是screen.width和screen.height，而screen的尺寸，一般由于性能问题，我们会限制为720p或者1080p，这样的话1440*2560肯定是超大了。 即便如此还不够，因为如果这个RT是为了bloom等效果，那么downsample的方式，也就是说尺寸为screen.width/2甚至screen.width/4。 2）AA的设置一般建议要设置为None的，AA在移动端太耗了。 3）格式设置为ARGB32问题倒不大，主要是尺寸限制好了，大小就小很多了。 4）Depth Buffer也会影响RT的大小。大部分RT实现的效果都不需要Depth Buffer，所以还是要看题主的RT是用来实现什么效果。如果不用Depth Buffer，比如图中的第2个RT应该就没开Depth Buffer吧。一张14402560的RT也不超过144025632/(10241024* 8)=14MB，当然14MB也很夸张了...还是需要降低尺寸。 感谢UWA问答社区 @王烁 提供了回答，欢迎大家转至社区进行进一步交流： https://answer.uwa4d.com/question/5a9e050a0b827e2c0bfdd0d4 内存管理 Q4：上图是三星S6上的数据，PSS比Reserved Total还小，而且升降很不一致。这个是正常的吗？我看在小米5s上倒是正常的。 三星S6： 小米5s： UWA：上述两张都是对的，因为都是通过系统API来获取的数值。之所以在不同机型上会出现差异，在我们来看主要是统计的内容不同。在我们测试过的大部分Android设备中，PSS是会将GPU所用的一些显存统计进去的，但会有一些机型除外，三星S6就属于这样的设备。所以，就会出现类似上述的现象。 OS版本不同、设备不同，其统计的PSS也都是不尽相同的。PSS是统计设备内存使用情况的一个指标，但对于内存优化来说，意义不大，我们建议还是以Profiler中的Memory数值为准。 该回答由UWA提供，欢迎大家转至社区进行进一步交流： https://answer.uwa4d.com/question/5aa161ea0b827e2c0bfdd0fc 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问答也许都只是冰山一角，像这样实用的知识点在UWA问答平台（answer.uwa4d.com）上还有一打！UWA欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 互动话题 AssetBundle Diff Patch 方案是否可行？ 除了比对AssetBundle文件的hash值直接替换整个AssetBundle和manifest来达到更新效果的目的，有没有其它方案类似diff patch，可以减小更新包体？如果可以做diff patch，资源颗粒度是不是就可以忽略了？
新年伊始，随着大家紧锣密鼓地开始了工作，UWA每周推送的知识型栏目《厚积薄发 | 技术分享》已经伴随大家走过了100个工作周。回顾两年多来，我们分享了近500个和游戏开发、优化相关的精彩问答。这些问答不仅有具象明确的提问，也有详细周全的解答；既能供研发团队自身项目中即学即用，还能通过参与者的回答分析，帮助我们在解决问题的过程中触类旁通、鉴往知来。我们优选了10个开放性的精彩回答，分享给大家。 UWA QQ群：793972859 UWA 问答社区：answer.uwa4d.com 1、如何在项目初期确定美术规范？ 在项目初期，没有任何正式美术资源的情况下，如何给出一个美术资源制作的规范给到美术呢？我明白，就上面的策划需求不能得出一个精确的制作规范，只是想要一个大概的推算方式，给出一些大概的参数，好让美术有规范可以参考。不知是否能给些指引？ 美术也可以按他们想要的精度先制作部分角色和场景，但只有有限种类的资源的情况下，有方法测算出这个精度在性能允许范围吗？也就是说这个精度满足策划需求，可以作为美术制作规范。例如只有一个角色（5000面，512贴图三张，80根骨骼），策划同屏要求20个，就在场景中摆20个一样的角色进去（因为只有一个），如果目标手机不崩溃，以后角色的制作就按这样做。这样可以验证这个精度吗？ 精彩回答1： 作为经历了一个新项目在大家都没经验的情况下做出一个刚小范围内测游戏的苦逼开发者，结合群里讨论，个人觉得以下经验可以参考： 1）选好对标游戏，扒资源来参考。比如畅销榜上的游戏，把资源解出来看，参考模型面数和贴图等游戏。这样最坏的情况下，参考别人能跑上线收到钱的游戏，收钱不保证，但是游戏性能的坑会少很多； 2）所有口头或文档的规范，都是无效的，不可能得到严格遵守，也就是说，不能用程序检测的规范都是空规范，全部做成Editor菜单检查校验； 3）用同一个英雄放20份测同屏的方法是不靠谱的； 4）从gfxbench.com上根据跑分选好基准机型，比如假设要兼容的机型是跑700帧的，那么基准机型得选6000帧的，预留好性能空间，性能别用得太满，否则没回旋余地: 5）贴图少用RGBA32，让美术在做图的时候，做出来一律以压缩模式的纹理来走Unity导真机包来看效果，千万别只是把美术图导手机相册里看效果，这会和真实的游戏效果有所偏差。建议规范只留两张2048*2048的纹理空间给美术发挥，其余全压缩，否则等美术在高画质模式作出效果后不肯降效果，逼程序优化，性能损耗非常大，程序会万分苦逼。 感谢李先生提供了以上回答。 精彩回答2： 这确实是个见仁见智并且取决于项目类型的问题，不过题主是在项目初期，想要快速迭代出策划的设计原型，并且要快速制作并且不用与程序产生过多沟通，在此前提下我觉得设定美术规范的首要目的是：不失控。制作出性能优秀的原型不是前期的目的，但毕竟是项目进展的一部分，如果美术资源制作没有标准规范参考，如果随便一个场景都是几十万面，DrawCall超过300，Overdraw可视化都红得发白，那到后面整个团队都要为此付出时间和精力，甚至返工。所以基本的制作规范也是十分必要的。 其次，在项目前期如何看待优化这个问题呢？我觉得过早的优化也是没有太大意义的，谈优化必须首先定位瓶颈，否则盲目优化除了降低资源质量和运算精度，对项目很难起到正面作用。这时项目处于快速变化中，不适合过早断定，所以在这个阶段依然是保证项目即使没有很优秀的性能，但是也没有很严重的问题，这就已经及格了。到了项目后期优化与效果的博弈，这又是另一个话题了。 在以上前提下，假设题主制作的是一个RPG游戏，主城+若干小副本推图，中端手机 iPhone 5，没有程序的太多干预，那么我的建议是： 1）大致规定好项目在 Unity 中的资源组织格式； 2）设定好 3dmax 导出模型的比例标尺，最好与 Unity 大小 1:1； 3）场景总面数均值5-6w左右（大部分），最高10w（少部分），单个模型300-1500面，摄像机可见部分2w以下，导出去除废点，多余的法线（如果没用的话），尽量单面； 4）场景总面数还要看同屏战斗人数多少做调整，Drawcall最好不超过50，一边给角色和特效留下空间，总 Drawcall 不要超过250这个尽量保证； 5）场景物体每个模型一个材质球，贴图256为主，正方形，pot(长宽2的倍数)； 6）严格限制场景中透明片的大小和重叠的个数，尽量少用，减少面积； 7）角色面数部分，主角1500以下；特殊boss2000以下；精英怪物1000面以下；普通怪物800面以下； 8）每个角色一个材质，除了特殊部件（翅膀等）一律不使用透明材质；贴图长宽相等，符合pot，128-256为主，最大不超过512； 9）去除 IK 节点和所有不必要的网格，对齐模型中心点与坐标原点； 10）预先规定好角色需要换装的所有节点名称，并且将需要换装的部分规定好并制作时拆开；（建议将脸部单独拆卡，脸部可增加面数）； 11）角色骨骼30-35根为主，特殊大boss适当增加，超过40慎重考虑； 12）可以考虑动画帧率10帧每秒，视具体情况或者不限制； 13）粒子单个发射器不超过50，每个特效最好10个粒子以下，同屏不超过500（200太低难以达到），尽量减少材质和粒子种类，大小，面积，层叠数等，粒子真的很费； 14）摄像机一定要调整远近裁剪面，尽量降低远近裁剪面的距离，默认数值过大，也千万不要图方便设置比如 0.1-2000这种，该数值极大影响低端机的深度缓存精度，引起过近的物体穿插闪烁； 15）使用最简单的线性雾，同时善用雾效和摄像机的 culldistant 功能，裁剪掉雾效淹没出的场景部件； 16）可向程序提出贴图导入自动处理工具，比如角色贴图：普通贴图 _D 结尾，法线贴图 _N 结尾，导入时工具自动设置大小和格式； 17）如果某个资源大于5MB，那么要仔细查看是否真的必要； 18）如果成使用工具完成的资源检查和设置，那么都尽量提出需求让程序满足； 19）最好有个人专门负责检查和整理资源； 以上只是摘取了一部分影响比较大的提了出来，也有一定的项目类型针对性，请根据自己的项目酌情参考和调整，实际细节还是比较多。另外，美术同学要善用 Unity 已经提供的各种工具，比如：面数, DrawCall，OverDraw 等等，这些都是直接又重要的基础指标，需要随时关注。美术同学也可以一开始不需要非常清楚这些标准背后的含义，尽量地去贯彻执行，久了就慢慢能理解，有空自己多去思考和追究；这些标准可以为少数情况酌情开特例，但不要太多。 感谢Yaukey提供了以上回答。 此问答来自于UWA 问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5941544c18d35e654e3e2373 2、美术资源导入管理 我们每次大批量地合入美术资源时，经常会出现构建出来的版本出现材质引用丢失、Animator Controller引用错误、贴图引用错误等资源引用错误的问题，美术资源在本地是正确的，其他人机器上Editor看也是正确的，构建机Editor看也是正确的，但构建出来的Bundle是坏的。有时删除Bundle再编会解决，有时则不行，目前遇到这种情况，只能让程序同事在构建机上删Meta重新做一次Prefab，费时费力而且不规范。 想问问这是Unity的Bug吗？大家有没有规避或者优化的方法？在管理美术资源合入的时候有没有更好的流程，我们目前使用Perforce管理Unity工程，要求美术显式上传资源配套的Meta文件。 精彩回答： 我根据我们项目遇到过的问题猜测下，我觉得项目资源导入某个地方有问题的可能性更大些，题主是否可能存在以下情况： 1）是否使用代码混淆。在Prefab 上挂的脚本忘记添加到排除混淆的列表，导致序列化的字段被混淆，打完Bundle后的Prefab资源加载时候，挂接的脚本出现引用错误； 2）资源导入都重载过OnPostProcess并处理了资源设置，这一步是否修改了什么不合理的地方，比如破坏了引用关系； 3）打包AssetBundle时，在构建Bundle 之前有没有使用文件操作API（不是 Unity 的AssetDatabase的API）来直接修改了某个文件夹或者其他会破坏引用关系的行为，然后构建Bundle，完成后恢复文件夹名字（或者恢复资源原始状态），这样丢失引用关系的几率很大； 4）有没有可能发布机器上，看着正常，但是Perforce里面已经存在一堆已修改的Meta文件；这种问题常出现于美术本地有两个A1，A2个相同资源在不同文件夹，A1受版本控制，但是由于某种操作，本地临时资源A2使用了原本A1的Guid，原本正确的 A1 被迫使用了不正确的新生成Guid（相当于两人交换），然后上传了A1的Meta，结果发布机器的下来的A1 Meta就会跟别人丢失引用，或者更新下来本地重新分配了新的Guid；美术策划最容易犯这个错误； 5）我们是Unity 5.3.8p2，上周遇到一个疑似bug，美术多上传了一组相同的资源，我们更新下来都会重新生成Guid，但是很多挂起的Meta在Unity里重新导入后，在版本控制里神奇地消失了，但修改还在； 6）如果都不是，只能尝试最小排除法了，删除项目绝大部分资源，一点点增加，然后打包，重现，排除原因；不行的话然后删除代码，一点点添加，打包，重现...有时候笨办法也是最容易接近真相的。 该问题来自UWA问答社区，感谢Yaukey提供了回答，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a0e8184e8a3d9357ce19473 3、Camera开启HDR对移动游戏的影响？ 我看到很多炫酷的效果都是用Unity的后处理来实现的，要求Camera开启HDR。但是我不知道开了这个选项会不会很耗，在中低端机上能跑起来吗？另外，使用HDR之后，Camera的Rendering Path是不是不能选Forward? 精彩回答1： 使用HDR可以选Forward，和Rendering Path的选择并不会相互影响。 在手机上单纯开启HDR(fp16)性能的影响并不会很大，各种后处理Pass的开销是要优化的重点。因为一般不会单纯开启HDR而不使用后处理，综合考虑到发热量等因素，不建议低端机器使用HDR和后处理，中高端再开启HDR并配合后处理，并对后处理做基础优化：比如适当降低后处理分辨率，尽量合并多个后处理流程到一个Pass等。 感谢贺甲提供了回答 精彩回答2： 开启HDR本身只是为后处理准备需要的数据，关键在于后处理的效率。假如说的是整个HDR实现的话，占GPU总体时间是一个相当可观的数值，大概可以认为是用带贴图透明片整屏绘制4，5遍左右的量（大概在这个数量级）。如果你只是想做泛光，使用更低质的效果的话，会好很多。 问题是，部分上古机型（诸如我的旧安卓机）本身对unity的后处理不兼容，只要对当前屏幕缓冲做任何操作都会导致卡死，不使用后处理主要是兼容方面的考虑，也就兼带着无法使用HDR了。 但是目前完全可通过兼容性测试来决定特定机型后处理的开关，一刀切的方式并没有必要。但这样又有一个问题：特定后处理提升的画面效果是否对得起它的消耗？是否有其他非后处理的方式可以实现类似的效果而消耗更低？（比如仅仅实现小物体的泛光用透明圆片堆叠效率比正常的Glow效率更高，虽然效果不好），这些也是导致后处理没有广泛使用的一个原因。 所以要看你具体想要实现的效果了。毕竟PSP这种机器末期在机能受限情况下也都在勉强实现后处理泛光效果，说明玩家其实还是有这样的需求的（虽然你拿出这样低质的效果很容易被产品BB糊了不如不加什么的……） 感谢唐翎提供了回答 精彩回答3： 手机上基本都是forward并不影响。不知道5.5.x情况。从5.6.x开始是可以通过设置Tier settings 来调整hdr mode. 有FP16也有R11G11B10格式。这两年手机GPU GFLOPS已经有了飞跃性的提升。附加个数据：比如meta9 一套4-5个后处理下来GPU消耗2-5ms. 感谢蒙占志提供了回答 此问答来自于UWA 问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/59f810692f7f63497e0f6baf 4、如何加快打包速度？ 目前我们项目打出来的APK大小在120MB 左右，打一次包平均耗时在20~25分钟。Build过程中绝大部分的耗时在“Building Scene0”和“Building additional assets”这两个阶段。请问这两个阶段Unity具体是在做哪些操作？有没有什么方式可以减少这阶段的耗时？另外如果从硬件层面考虑，如何更有效地提高打包速度？提高硬盘的读写速度和CPU的性能又分别能带来怎样的耗时收益？ 精彩回答1： 我们使用的是AssetBundle的方式，目前600MB的包，没有太多资源修改的情况下，安卓包出包大约10分钟左右，之前是7-8分钟，不修改C#代码单独出Patch的话大致在5-7分钟。 我们在用的安卓打包机价格大约是1万左右，多CPU并且保证单核CPU的性能也是尽量高一些，SDD肯定必备，其他的没什么关系。 我们的CPU使用的是：Intel（R）Xeon（R）CPU E5-2683 v3 @ 2.00GHz 2.00 GHz 提醒一下关于贴图压缩，之前我们一直被贴图压缩折磨，高品质实在是太慢，后来我们是区分了Dev和Pub版本，Dev版本本地贴图压缩使用Fast，发布用的Pub版本才用Best的品质，速度快了非常多~即使美术大量修改贴图，Dev版本出包也很快。 感谢贾伟昊提供了上述回答。 精彩回答2： 我很久之前在Github上发现了这个东西： pvrtextool_wrapper：https://github.com/fxgames/pvrtextool_wrapper Unity打包会调用pvrtextool，通过这个wrapper替换掉原始程序，这样可以在打开发版本时，强制把压缩质量设置到fast模式，这样就可以节约大量的时间，而不需要修改任何贴图的压缩质量参数。如果觉得Mac Pro太贵了，可以试一下这个方法。 感谢lujian提供了上述回答。 精彩回答3： Building Scene 是Unity在打包场景资源中，Building additional assets 是Unity在打包Resources中的资源，我们项目接近600MB了，每次出包都要50分钟以上，苦不堪言。你可以尝试这样： 1）把资源全部使用AssetBundle的形式。除了第一次，在下次出包的时候，只会打包有变化和增量的资源。因为Resources的每次出版本都会重新打资源。这样可以将没修改的资源打包耗时省下来。 2）配置个好的电脑，把CPU换个好点的，硬盘换成SSD的。 以上2点能节省你出包的时间，目前也是我们使用的方法 感谢 hejianchun提供了上述回答。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a7abe4d847802258a06503d 5、如何在PC上检查美术的特效性能？ 有没有比较好的办法在PC上检查美术的特效的性能？我们之前做了个粗略的方法，就是扔N多特效在场景里，检查一下帧数，但是效果感觉不是很好，想听听大家的意见。 精彩回答1： 我们是写估分公式，也就是按一定的规则，遍历整个特效，根据节点的属性计算一个性能分。可以批量扫资源输出Excel查看。复用一下代码可以直接植入到编辑器，让美术做的时候就看到这个分。 不用很精准，这种方法90%的问题都可以很快发现。还可以预先定好规范，结合特效的使用情景来估算特效同时出现数*特效性能分会不会超标。 感谢招文勇提供了回答。 精彩回答2： 特效吃性能主要是OverDraw导致的。我们没在PC上检查，是拿真机检查。 PC的检查是用了钱康来提供一个看OverDraw的脚本，美术可以在做特效的时候大概看一下OverDraw，根据情况来调整。 然后我们构建真机包的时候生成特效列表名单，然后在进到主城之后，在聊天节目输入GM命令，遍历播放特效，每个特效可以通过播放1到n份，然后通过AdvancedFPSCounter插件记录当时的FPS值，记录到文件里。 然后找出帧率低的时候是哪些特效，然后针对性优化即可。 比如代码 if (cmd.ToLower().StartsWith("-gm texiaoplay3")) { Toast.ShowTip("测试美术做的一系列特效 " + cmd); prEffectTest(3); return true; } private static void prEffectTest(int efCount) { if (BilinCamera.Instance == null || BilinCamera.Instance.player == null) { Debug.LogError("找不到场上英雄，因此不能测试特效"); return; } TextAsset conf = Resources.Load<TextAsset>("effeclist"); string[] lines = conf.text.Split('\n'); //先同步加载一遍 for (int i = 0; i < lines.Length; ++i) { string prefabName = lines[i]; if (string.IsNullOrEmpty(prefabName)) { continue; } } BLDebug.isLog2FileEnable = true;//开启写文件 GameManager.Instance.StartCoroutine(prEffectTestAsync(lines, efCount)); GameManager.Instance.StartCoroutine(logUsedFPS(efCount)); } private static IEnumerator logUsedFPS(int efCount) { float startTime = Time.realtimeSinceStartup; float crtTime = Time.realtimeSinceStartup; while (crtEffectName.Length > 0 && (crtTime - startTime) < 6000.0f) {//100分钟内 crtTime = Time.realtimeSinceStartup; CodeStage.AdvancedFPSCounter.AFPSCounter aFPSCounter = CodeStage.AdvancedFPSCounter.AFPSCounter.AddToScene(); BLDebug.Log2File(TimeUtil.currentSqlTimestamp4LongAdv() + "\tlogUsedFPS" + efCount + "\t" + crtEffectName + "\t" + aFPSCounter.fpsCounter.LastValue + "\t" + aFPSCounter.fpsCounter.LastAverageValue + "\t" + Time.frameCount + "\t" + Time.realtimeSinceStartup); yield return new WaitForSeconds(0.1f);//每0.1s采样一次fps } yield return null; } private static string crtEffectName = "notbegin"; private static IEnumerator prEffectTestAsync(string[] lines, int efCount) { float periodTime = 5.0f; //开始逐个播放特效 for (int i = 0; i < lines.Length; ++i) { string prefabName = lines[i]; if (string.IsNullOrEmpty(prefabName)) { continue; } crtEffectName = prefabName; GameObject[] effectGoArr = new GameObject[efCount]; for (int k = 0; k < effectGoArr.Length; k++) { GameObject effectGo = PrefabUtil.loadPrefabToGameObject(prefabName, parentGo); effectGoArr[k] = effectGo; if (effectGo != null) {//是ui特效， GameObject.Destroy(effectGo, periodTime); } else { Debug.LogError("加载失败？？？" + prefabName); } } yield return new WaitForSeconds(periodTime); } crtEffectName = ""; BLDebug.UploadTodayLogFile();//把当天的日志传到服务器 yield return null; } 把日志导入Excel进行分析即可。 感谢李宗波提供了回答。 精彩回答3： 我们分了两块： 1、特效释放对于整体性能的影响部分，这个是针对结论性的统计，在真机上统计释放之后的帧率波动，目前的版本只做了往场景里扔来记录帧率的功能，主要评定特效对于游戏最终的影响； 2、特效的Draw Call、面数和Overdraw影响。这块的统计数据的获取我们目前只能在PC上获取，所以有一个工具在单机版本里逐个播放技能特效，统计对于上述三个指标的评价，找出超标的部分每周周会上给出报告列举出来。 个人感觉资源的检查一定有工具定期来做，持续监控才是最有效的优化方式。 感谢贾伟昊提供了回答。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a3b96e934968145049616fe 6、Graphics API的选择 大家现在在工程里还是选择只使用 OpenGL ES 2.0吗？我记得以前大家都是这么做的，现在这个做法过时了吗？iOS 是否该加上 Metal？ 精彩回答1： 我们目前都是用的Auto，主要有两个原因： Metal测试下来CPU Overhead会比GLES低很多 GLES3能够有tex2Dlod支持 兼容性上来说只有实在老的机器和模拟器会fallback到GLES2，可能效果上会略差一些不过我们测试下来都可以接受。 感谢钱康来提供了以上回答 精彩回答2： 我们现在快要上线的项目选的是ES3.0，iOS和Android都是选的这个，iOS选Metal的时候遇到模型显示不正常的问题，但是能力有限加上没时间没定位到原因，就统一成ES3.0了。选ES3.0还有一个原因，就是发现AssetBundle打出来的资源会比选Auto小很多。 还有就是目前我们的游戏偏重度，不指望用老手机的玩家会付费，所以放弃显卡太老的机型了。 感谢李先生提供了以上回答 此问答来自于UWA 问答社区：如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/594ddec949dc1fb06ce0685f 7、多维度材质对效率的影响 在目前的Unity版本中，使用多维材质是否会对效率产生影响，用多维材质和把模型分块哪个更好？ 制作美术资源时，应该尽量避免使用多维材质。先举例说明多维材质的一个优点是拆分模型做不到的： 一块大石头有石头和草地两个材质，做成一个整体的模型，使用多维材质，作为一个物件进行烘焙，在Lightmap上的UV分布是一个整体，不会出现拆分为两个模型烘焙产生的接缝问题。 除了上面这种情况，其他情况下推荐将模型拆分成多个模型赋予不同的材质。优点是： 1、多个模型会作为多个MeshObject参与到裁剪、静态批次等优化中； 2、拆分的模型和贴图可以进行材质合并，程序才能进行下一步的优化，如果本身是多维材质，就无法进行合并DrawCall的优化； 第一个优点就能带来很大的收益。制作上应该按照一个模型对应一个贴图的做法进行，如果模型是一个整体，比如房子由底座、墙体、屋顶组成，建议将他们多选导出成一个FBX。 另外，不同材质的模型建议做成多个模型，再多选导出成一个FBX，仍然是一个模型对应一个贴图的规范进行制作。 该问题来自UWA问答社区，感谢文雅提供了回答，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/59e890dbe02a95cc6d0c4987 8、AssetBundle粒度规划 关于AssetBundle（下称“AB”）拆分粒度问题。在我的项目中，我是基于逻辑以及最终的打包大小来分的，比如尽量不让压缩后的AB包超过1MB, 这是UWA之前的推荐，同时也是因为当前版本Android包的SerializedFile占用大小（https://blog.uwa4d.com/archives/TechSharing_56.html）所考虑。经过这样的规划之后，我打包这块的代码基本是写死的， 包括手动把公共包拆成多个(公共包略大，不拆的话压缩后会有6、7MB)， 还有每个AB包的内容也是人为拆成多个。 这样虽然最后功能实现了，但个人依旧觉得不够自动化。每次新添加资源的时候， 都得走一遍这种手动流程。也研究了别人写的开源方案（https://github.com/tangzx/ABSystem），全自动分析依赖关系，但问题是最后包打得实在太细了，不太符合科学(但还是推荐大家学习)。所以就想问下各位的公司项目是如何解决这个AB 粒度划分问题的？ 精彩回答1： 这是一个相当开放的问题，仁者见仁，智者见智。UWA目前无法总结出一个统一的方式来建议如何进行打包，首先需要说明我们看到的两点情况： 1）没有最好的打包方式，只有最适合项目需求的打包方式； 2）无论是粗粒度打包还是细粒度打包，现在都有成功的项目在采用，这说明只要符合需求，两种打包方式都是很好的。 接下来，我们就粒度问题给出一些我们的看法： 1）AB粒度建议不宜过细，特别是一个资源一个AB 粒度过细，一方面会导致加载IO次数过多，从而增大了硬件设备耗能和发热的压力；另一方面，在我们测试过的Unity 5.3 ~ 5.5 版本中，Android平台上在不Unload的情况下，每个AB的加载，其每个文件的SerializedFile内存占用均为512KB（远高于其他平台），所以当内存中贮存了大量AB时，其SerializedFile的内存占用将会非常巨大。同时，需要进一步说明的是，该问题已在Unity5.6中进行完善。 2） 在Unity 5.3版本之后，对于AB文件的文件大小其实不必再限定于1MB之内 之前UWA有这一限定是出于两方面的考虑：一是New WWW在Unity 5.3之前是使用最为频繁的AB加载方式（虽然现在也是），在5.3版本之前，New WWW加载会形成一个比较大的WebStream，一般来说是压缩AB的4~5倍，会占用比较高的内存；另一方面，当AB较大（比如大于5MB）时，其加载开销会很大，由于是子线程中运行，所以真正反映到Profiler中时，大家会看到的一个“诡异”的CPU高开销——Graphics.PresentAndSync，具体原因可以看这里（ 扒一扒Profiler中这几个“占坑鬼” ）。所以，我们对此做了一些实验，发现将AB压在1MB以下是一个加载比较可以接受的情况。以上是我们之前为什么会提出1MB的主要原因。但Unity5.3之后，随着LZ4的引入，很多情况已经变化了，基于其Chunk的加载特点，AB加载很快，且内存占用要比之前小很多。所以LZ4的AB其实可以考虑更加粗粒度一些。 但是，这里仍然有以下三点注意： 1）对于需要热更新的AB，也如问答中其他朋友的所言，要考虑实际情况控制AB的大小； 2）即便是LZ4的AB，其加载方式不同，加载效率也可能完全不一致。以下是我们在UWA DAY 2017的分享，我们在两个不同的AB（LZ4格式）中都加载同一个资源，唯一不同的是一个AB包含10个Asset，而另一个AB包含30个资源，以下是三种不同方式从加载AB到AB.Load的耗时对比。可以看出，New WWW加载出现了明显的时间差异。因此，在Unity5.3之后，尽可能建议通过LoadFromFile(Async)来对AB进行加载。 3）对于AB的打包，尽可能把逻辑上同时出现（一个Prefab中非Share的Asset）、小而细碎的资源（Shader、Material、粒子系统等）尽可能打包在一起，并通过LoadAll来进行加载，因为这样会带来更好的加载效率。下图为LoadAll和Load One By One的性能对比。在我们做过的实验中，LoadAll确实会带来更好的性能开销。 上述是我们建议研发团队在AB打包时的一些注意点，希望对大家的项目优化有所帮助。 此问答来自于UWA 问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/58e5bd96e042a5c92c3484ec 9、优化数据表的加载 安卓客户端存在大量的模板数据需要配置，其中一些模板表甚至可能达到万级的数据条目，那么怎么对这些数据模板表进行打包和加载，可以兼顾加载速度和热更新表结构？目前的方案是采用Protobuf代替ScriptableObject进行序列化，可以实现热更新模板表结构，但是加载速度相对ScriptableObject有较大的差距，目前数据模板加载较慢便导致了玩家进入世界的时间比较久。因此想了解大家有什么好的建议呢？ 精彩回答1： 本地读取数据表是个老话题了。我不能完全解答这个问题，只能提供一下我过去项目的浅显的经验。用ScriptableObject或者BinaryFormatter二进制存储然后反序列化成保存数据结构的对象，这两种方法应该是加载速度最快的。 我们实际没有采取这个方案，也使用的是Protobuf，是出于以下考虑: 一份二进制数据，客户端和服务器可以通用。从服务器推数据很方便； 策划习惯使用Excel编辑，有脚本可以把表格内容导出成Protobuf的二进制数据，另外，还有.cs/.go表结构描述文件需要重点考虑。也就是说，策划修改表结构、增减表，服务器和客户端的结构描述文件可以自动生成好； 实际用下来，确实会有一些差距。如何选择还是要看表格的体量了。 感谢WangLiang 提供了以上回答。 精彩回答2： 我先把问题拆分一下，题主遇到的问题如下： 第一个问题：配置表存储格式 现在主流的数据存储基本分为三大类，各有优劣，需要根据实际情况选择： 1、ProtoBuf或类似序列化库，这种方式兼容性高，但是加载速度一般； 2、自己实现二进制数据存储，兼容性差，需要精心设计达到较高的数据表达能力； 3、采用Lua热更新方案的游戏，普遍直接把数据存储为Lua表。 第二个问题：配置表数据与代码兼容 一般不建议大量修改数据结构，比如增删字段，如果实在无法避免，需要代码连同数据一起发布进行热更，做好版本管理即可。 第三个问题：配置读取速度优化 1）先从数据量上约减，减小数据冗余重复，数据存储设计优化，多次引用的字段多引用等等； 2）采用多线程加载，避免使用Unity提供的API，在游戏启动时，并行加载配置表，充分利用多核优势； 3）就我们自己项目而言，没有使用Lua的更新方案，但是我们依然采用Lua作为了数据存储，经过优化后加载速度也不错，可以参考 LuaTableOptimizer。 感谢Lujian提供了以上回答。 如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5981c5c5c08748f866b5ebe2 10、Unreal 4 Shadow Map Cache 我想问下Unreal 4的 Movable光源的Shadow Map Cache问题，它的具体更新策略是什么样的呢？如何处理动态物体与静态物体的关系？需不需要对Shadow Map进行Cascade？ 我同时也参考了Cry Engine的文档： http://docs.cryengine.com/display/SDKDOC2/Cached+Shadows 同时如果想移植到Unity，可行吗？或者我想解决大面积实时阴影的问题（光源方向会变化，大部分物体是动态物体 但是频率都不高）有什么解决方案吗？我可以在光源Space下预烘焙数据来达到光源方向变化，用一张Shadow Map的可能性吗？类似 Directional Light Map那种建立空间的？ 精彩回答1： Unreal 4的这个Movable Light的Shadow Map Cache只能给Static、Stationary物体用，因此我觉得其实是想给Movable光照下的Static物体阴影计算做个优化。但是Mobile端没必要用Movable，Stationary就好，Static物体的阴影是预计算的。 Unreal 4的动态物体在计算阴影的时候会计算两次，一次是从静态场景投射到动态物体，一次是动态物体投射到静态场景。在计算静态场景投射到动态物体阴影时，引擎会缓存一张静态场景的Shadow Map，用于计算投射到动态物体上的阴影。因此，对于动态物体也能接收到来自静态场景的精确阴影遮挡，但是这个方式比较耗时，而且mobile也不支持。 Unreal 4也提供了类似Unity的对静态场景投射到动态物体阴影近似解决方案，也是将shadow的预计算结果存储到带有间接光信息（也是SH）的点云（在Unity中就是light probe）中，然后根据动态物体的位置从点云插值出阴影遮挡，但是这种方式只能得到物体整体明暗度的变化，无法计算精确阴影。Unreal 4是推荐mobile上使用后面一种方法的。 需要补充一下的是，Unity解决动态物体接受静态物体烘焙阴影也是采用Light Probe的。题主说是动态光源，动态物体，最好还是实时阴影计算。如果是采用Shadow Map Cache的方案做优化，可能得看具体场景和需求。预计算烘焙多个Shadow Map的方案可能需要考虑两个因素，一是光源变化，二是动态物体变化。如果动态物体和光源变化频率都不高，那么可以尝试对它们采样预计算好Shadow Map。但是这样带来的Shadow Map占用空间和内存开销我们也不清楚，可能得尝试一下才知道。 以上回答由UWA提供。 精彩回答2： 关于Unreal 4的实现，楼上已经说得很详细了，可以参考Unreal 4源码ShadowSetup.cpp/ShadowDepthRendering.cpp，搜索SDCM_StaticPrimitivesOnly相关的代码即可，我补充一下其他问题： 1）针对动静物体怎么处理 在手机上比较难完美，可以针对静物渲染一张SM，动态物件用planar shadow解决 2）Shadow Map Cascade 缓存的话，Shadow Map不能随时更新，如果镜头频繁大距离移动，cascade不能跟随镜头随时更新，过度可能会不自然，这需要根据项目特性权衡 3）能不能光源动，Shadow Map用同一张 看你怎么动，如果是模拟日光，轻微转角，那你只能放弃精确阴影计算，在判断某个空间点是否在阴影区时增加偏转角，相当于把阴影做平行四边形变形 如果想360度转，目前我也没有很好的思路能兼顾cache和平滑转动时的过度，毕竟物体的四面都长得不一样，不可能用一张shadow map做平行四边形变形而不穿帮。 感谢招文勇提供了回答。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a0e6dc2e8a3d9357ce1946d
本期聚集了这些话题：AnimationClip的AB文件大小、不同Unity版本的AB文件大小不一致，AB前后打包的CRC值不一致...... UWA一下，你就知道~ 我们将从日常技术交流中精选若干个开发相关的问题，建议阅读时间15分钟，认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。 UWA QQ群：793972859 UWA 问答社区：answer.uwa4d.com 资源管理 Q1：最近在做包体压缩，发现有些动画文件的AssetBundle文件比较大，观察发现是其中包含的Clips较多，但是这些Clips都是复用的，而只是动画轨上挂的事件不同，所以创建出来的。 我们使用了LZ4的压缩格式，这个文件的大小大约是800K+，偶然测试使用了非LZ4的形式来打包，这个文件的大小大约是60K左右，相差有10倍以上的差异，这个就比较奇怪。 不知道有没有别的项目遇到过这样的问题，我尝试从原理上理解： 对于这种重复的动画，数据是可以复用的，动画事件相当于存储一些额外的配置就够了，所以理论上增加这种复用式的Clips不会对AssetBundle文件有多大的影响。LZ4因为要支持Chunk式的加载，所以复制了动画信息到所有的Clips的Chunk上？因此数据比较大？ 想问下我的猜想是否正确，这种情况下，有没有什么好的方法压缩一下这块的体积？ 两种格式下的AssetBundle文件大小差异： 是可能存在这个问题的。使用了LZ4压缩的动画文件AssetBundle大小，与Animation面板中Clip的数目和每个Clip的大小成正相关。 因为无法看到源码，只能说下我的理解：在打包AssetBundle时如果选择LZ4压缩，其将动画文件中的每个Clip作为独立的资源来单独压缩，这样可以保证在解压时只解压需要的Clip，但这样也就隔断了不同Clip间重复数据的复用，从而造成AssetBundle体积随Clip数目增加而变大。一个简单的例子就是，当你增加多个哪怕是完全相同的Clip时，AssetBundle文件也会随着Clip数目增多不断增加（很容易超出动画Fbx的大小）。 而默认的LZMA压缩，压缩时将整个AssetBundle作为一个整体（当然解压时也需要对整个AssetBundle解压），因而能充分复用不同Clip间的重复数据，因此，压缩后的AssetBundle大小对分割的Clip并不敏感。同样的例子，对动画文件增加多个Clip后，使用LZMA压缩的AssetBundle依旧会保持很小，而且增加不同的Clip数目，其大小也基本不变。 如此一来，如果要通过压缩减少动画文件AssetBundle体积，可以对解压速度不太敏感的动画文件用LZMA压缩。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a5cbf773513a24bd4ee76e2 资源管理 Q2：我在Unity 5.3.8 和5.6.5 下进行同样的设置，为什么FBX打出来大小相差那么大？ Unity 5.3.8 ：35K， Unity 5.6.5 ：400K，相关的例子已经上传至UWA问答网站。 看了下题主的AssetBundle文件，可以提供以下线索： Unity 5.6的Bundle： Unity 5.3的Bundle： 可以看到两个Bundle的差异在Shader，然后在Unity 5.5的更新文档中看到： Shaders: Shaders are now exported to the Unity player completely in binary. There is no Shader text string and parsing in run time. 也就是说，Unity 5.6的Bundle中Shader已经被编译为二进制，而Unity 5.3的Bundle中仍然是Text的Shader，从而导致了Bundle的不同。 该问题来自UWA问答社区，感谢 Saber 提供了回答，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a5ecc8ce6353e6be1f4342e 资源管理 Q3：我场景打包的AssetsBundle每次都不一样，和这个问题类似（https://answer.uwa4d.com/question/58d24e477dc35e7f0efb470f ）。 我已经修改了Strippt Shader的设置，并且每次都在同一个空场景下打包，但是打包出来的CRC值不一样。 我每次都是先删除本地资源，然后从SVN上CheckOut下来再打包。场景用到的Shader单独打一个Bundle，这个Shader的包也是不同的。并且Unity 5.6.2的打包API只是一个根据Bundle Nname打包的函数，我无法实现每打一个就切换当前场景。 首先相同资源多次打包确实是会出现MD5不同的，这个问题之前在Unity的Roadmap中是提到的，现在找不到了，说明可能在某个新版本中解决了。 但在之前的版本中，已知的有两种可能会导致场景的AssetBundle的MD5变化，一种是题主提到的那个问题(Shader Stripping)，另一种是开启Static Batching后，每次打包生成的Combined Mesh（或者其次序）可能不同。当然可能还有别的原因。 所以，建议通过AssetBundle的Hash值来判断内容是否发生变化（Shader Stripping的问题是会导致Hash变化的，而Combined Mesh那个问题是不会改变Hash值的），也可以通过AppendHashToAssetBundleName选项，直接把Hash值作为AssetBundle名字的后缀来查看。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a58b1b2332fcc45bafb1d95 其他 Q4：请问，WWW或UnityWebRequest通过域名下载AssetBundle，如何得知资源的实际IP地址？我用Dns.GetHostAddresses有时候会得到两个IPv4的地址，我如何知道实际连接的是哪个？ 我用Dns.GetHostAddresses的IP会变化，所以感觉不能保证WWW实际连接的IP是我上一次用Dns.GetHostAddresses取到的IP。需求是要log客户端在不同地区连接的CDN节点IP和资源下载速度。 域名和IP本身就不是1对1的关系，一个域名可以解析出多个A记录或者CNAME记录（例如CDN）。 Dns.GetHostAddresses获得就是域名对应的A记录信息，可以参考dig命令的输出。一般来说可以自己对返回的IP进行遍历来分别尝试使用。 至于WWW或UnityWebRequest内部是如何实现这个不确定，也许就是只处理得到的第一个IP，也许会对每个IP都进行尝试直到成功。 该问题来自UWA问答社区，感谢Jay提供了回答如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a5d71adf6dfce42a1f8ebd2 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站（answer.uwa4d.com）上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com 官方技术QQ群：793972859（仅限技术交流）
手游开发和优化的时间一直是寸土寸金的，随着中国移动游戏的精品化趋势日趋明显，整体表现都在迅速向端游品质进行靠拢。随之而来的，则是各种性能压力的急剧上升，优化工期的不断延长。如何在紧张的工期内，实现时间的最大使用价值呢？ 为了最大程度优化测试和优化的时间，我们推出了本地性能优化工具，为游戏研发团队提供性能数据分析的同时，还大大提高了大家的优化工作效率。据统计，截止目前使用UWA GOT的团队已经超过300家！ UWA GOT 是什么？ UWA GOT 全称 Game Optimization Toolkit，是由侑虎科技研发的本地性能测评工具。它既能方便研发团队在本地直接进行真机测试，也支持在Unity Editor中搭建本地服务器来接收和分析性能数据。整个测试过程中，研发团队能自定义测试时间和流程，几分钟后即可查看性能数据。目前提供 Performance Overview、Mono Memory Analysis 和 Runtime Asset Tracker三大功能的数据分析，从此为大家的项目性能又增添一份安全堡垒！ UWA GOT 使用步骤 为什么大家都选择UWA GOT？ 300位技术买手实力证明！ UWA GOT 的优势在于快，那么它到底为大家省下了多少时间呢？不妨让我们看看各位开发者朋友的买家秀吧！（感谢诸位技术大佬倾情代言！） 仅用一个多小时，对大型项目找出了针对性的解决方案 快速定位性能热点 功能全面、使用方便 节省大量时间成本 采集数据详细又简单 利用帧对比定位了资源内存泄漏 加快版本复盘和迭代的效率，性能提升立竿见影 便于团队协作 资源问题一目了然，减轻大量优化工作 便于反复调试和定位全局问题 想开发者所想，不断推陈出新 为了满足开发者更多样化的测试和优化需求，UWA也在不断收集用户的反馈意见并加以完善。今天我们发布了UWA GOT 最新版本v 1.0.4，该新版本主要支持了对游戏启动时间内的堆内存分配统计，对于不少开发者来说，这又是一个非常友好的功能。 为什么这么说呢？因为在定位堆内存分配时，开发者在UWA的在线性能测评报告中常常会看到类似下图中的曲线。 从中我们可以发现，在开启测试时，Mono堆内存峰值已经到达100MB以上，这表明在游戏刚开启时很可能分配了大量的堆内存。 那么在游戏启动的那短暂的时间内，引擎到底做了哪些工作，分配了多少堆内存呢，具体又是怎么分配呢？为此UWA GOT增加了Direct模式来解决这问题，当点击Direct Mode并使左侧按钮变绿后再点击某个模式，App会自动退出，而在下一次开启时则立即开启测试。 这些贴心巧妙的功能还只是冰山一角啦，关于UWA GOT更多功能，请查看：搞定这些问题，一个插件就够了！ 小编建议大家及时在官网下载最新版本，以体验更完整的功能：https://www.uwa4d.com/index.html#download
过去的一年，MOBA手游市场容量变得空前庞大，成了众多CP和发行追捧的对象，同时，其重社交、重玩法、重美术效果的高要求使得该品类游戏也面临着前所未有的性能挑战，那么当下市场上的MOBA手游性能呈什么样的状态呢？我们能从这一年的性能数据中找到什么规律呢？今天，我们将为大家分享MOBA手游性能的深度剖析。 今天分享的这份蓝皮书，收集了提交到www.uwa4d.com上的所有MOBA项目，我们从总体性能数据、引擎各模块开销、内存占用等方面进行了汇总分析，呈现Unity手游行业现状。 这是侑虎科技第291篇原创文章，欢迎转发分享，未经官方授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。（QQ群：793972859） 报告目录： 一、MOBA手游总体性能开销分析 二、MOBA手游CPU模块性能开销分析 三、MOBA手游内存模块性能开销分析 四、MOBA手游资源管理分析 五、UWA对于MOBA手游研发团队的建议 说明：我们选择了测评次数最多的四款机型来进行统计，这四款机型分别是红米2、红米Note2、华为6Plus和三星S6。同时，由于中低端设备性能是研发团队更为关注的部分。因此，本报告中的性能趋势分析以MOBA项目在中低端设备的性能数据为主。 一、MOBA手游总体性能开销分析 Android设备的CPU均值主体范围为16~61.2 ms，且主要集中在17~50ms范围之内。 无论是高、中、低端的Android设备，渲染、UI、加载/代码都是需要研发团队重点关注的，它们的消耗总和占了总开销的80%。 下面我们就来具体分析这些主流模块的开销情况。 二、MOBA手游CPU模块性能开销分析 1、渲染模块 严重程度：地狱 为了能够更好地反映出各个性能参数的整体使用情况，我们统计了每种性能参数的主体使用范围，其范围区间是[5%~95%]，以下数据中P5代表5%，P95代表95%。 在Draw Call使用上，MOBA手游的使用程度大幅低于MMORPG和ARPG手游，且对Draw Call的控制同样较好，UWA建议Draw Call占用的P95 < 200，86%的项目可以将其控制在这个范围内。 MOBA手游的场景渲染三角形面片数量普遍较高。且设备性能越高，数量峰值越高。经过统计，在中低端设备中，46.6%的项目能将渲染三角形面片数控制在100K以下。 2、UI模块 严重程度：地狱 使用NGUI作为UI解决方案的项目占据了相当高的比例，NGUI目前仍然是MOBA研发团队对于UI系统使用的主要解决方案。MOBA是目前手游中工程技术难度最为复杂的游戏品类之一，对于UI模块的选择，大多数团队仍然倾向于从稳定性和把控性两方面出发，这也是NGUI占比持续较高的主要原因。 下面我们将分别说明NGUI和UGUI的CPU耗时和堆内存占用情况。 UI模块的性能开销依然很高，也是我们统计中的重要性能杀手。在中低端设备上，超过80%的研发项目在UI端都面临较为严重的性能问题，主要体现在以下几个方面： （1）同一时刻存在大量需要更新的Panel，比如，攻击时刻的血条、不断移动的伤害数字等HUD。这些在“人堆”中范围攻击时或者进攻高地时是很容易大面积出现的； （2）不断滑动的摇杆和点击的技能icon，这些是MOBA战斗场景中使用最为频繁的UI元素，研发团队需要时刻注意这些icon的变动是否会带来较大范围内的重建。 以上情况都是MOBA项目研发团队每天面对的主要UI问题，可能一个Widget的使用疏忽，就能让研发团队的UI模块性能开销飙升一个量级。 注意：从重要函数上来看，UGUI的CPU占用大幅低于NGUI。需要说明的是，Unity 5.2版本之后已经开始将UI的部分计算操作移到子线程中进行，而主线程中的表现则为WaitingForJob、PutGeometryJobFence等，在本次报告中，我们并没有将这两项开销统计在内。 经统计，NGUI中堆内存每10000帧分配的主体范围为 5.4~53.2 MB，UGUI中堆内存每10000帧分配的主体范围在5.2 MB以内。从堆内存分配来看，UGUI远低于NGUI。 3、逻辑代码 严重程度：噩梦 1）GC触发频率很高，是造成卡顿的主要原因之一，目前只有48.7%的项目可以将GC的触发频率控制在1000帧/次以上。 2）在2016年GC平均耗时下降趋势明显，但在2017Q2出现大幅上升趋势，对此，建议研发团队在后续研发过程中对GC操作和耗时进行密切关注。 Shader.Parse 操作是比较突出的性能杀手，目前平均每次调用的CPU耗时主要分布在 6.4~171.3ms。但随着越来越多团队了解该项的耗时特性后，该项的CPU耗时呈现出较为明显的下降趋势。 4、动画模块 严重程度：噩梦 Animator.Update/Animation.Update的开销在中低端设备上的耗时呈现逐步升高趋势，对此，建议研发团队重点查看本篇文章的最后一节，我们提供了进一步完善和优化动画模块性能的相关方法。 5、粒子模块 严重程度：普通 1）粒子系统的CPU开销普遍很低，且近一年来下降趋势较为明显。 2）粒子系统的数量使用仍然较大，这会造成较高的内存占用，虽然2016 Q4和2017 Q1已经大幅下降，但2017 Q2随着新项目的增加，粒子系统的使用数量又开始大幅增加。MOBA项目中存在粒子系统数量较大的原因，主要是特效和技能的缓存所致。为了保证战斗时（特别是团队时）技能释放的流畅性，研发团队会选择在场景加载时即缓存英雄的所有技能，因此，MOBA游戏在战斗副本中会出现较大量的粒子系统缓存现象，特别需要研发团队关注。 三、MOBA手游内存模块开销分析 1、总体内存 严重程度：地狱 可以看到，MOBA游戏总体内存在2016年上升趋势明显，而在2017年内存占用则较为稳定。为了兼容市面上的中低端机，Unity引擎的实际内存占用需要尽可能被控制在300MB以下，这点是各大MOBA研发团队今年优化阶段的重中之重。 2、总体堆内存 严重程度：地狱 堆内存使用在2016年大幅下降，但今年随着新项目的涌入，其上升趋势明显，建议研发团队重点关注。对此，UWA建议重点关注以下几点： 1）严格关注配置文件的使用，避免一次性加载过大的配置文件而撑大堆内存； 2）不少项目的堆内存增大是由于热更新所致。因此，对于过大的数据Data的使用，建议通过分帧进行，并及时进行GC回收； 3）避免不必要的代码堆内存分配，虽然是老生常谈，但从趋势上可以看出，大多数研发团队仍需加强重视。 项目的内存占用很大一部分来自于资源的使用，下面我们将对项目中主流资源的使用情况进行分析。 3、纹理资源内存 严重程度：地狱 1）纹理内存峰值主要分布为 40~147.3 MB。 2）从走势中可以看到，随着MOBA项目的精品化趋势，其纹理内存占用也大幅提升，虽然2017Q2稍有下降，但依然拥有较高的内存占用。 4、网格资源内存 严重程度：噩梦 网格资源内存峰值主要分布为 14.1~ 65.9 MB，且上升趋势明显。对于场景、角色的网格资源控制，是研发团队在后续研发团队中需要关注的重点。 5、动画资源内存 严重程度：普通 动画资源内存峰值主要分布在9.2~38.5 MB以内，从走势中可以看出，2017Q1的内存占用达到47.1MB，而2017Q2的内存占用迅速回落到18.4MB。经过进一步分析，其主要原因如下： 1）2017Q1大量新游戏的涌入直接提升了该阶段的内存占用； 2）2017Q2动画资源新优化方式的推广，大量研发团队从中受益，从而内存占用大幅回落。关于动画资源的优化建议，建议研发团队查看UWA之前推送的技术文章《Unity动画文件优化探究》。 6、Shader资源内存 严重程度：噩梦 Shader资源内存峰值占用主要集中在0.1~7.9 MB区间之内。需要提醒的是，研发团队需要密切关注Standard Shader的使用情况，因为该类Shader在解析时不仅会造成较高的CPU开销，同时会造成较大量的内存占用。 7、RenderTexture资源内存 严重程度：普通 与MMORPG和ARPG手游不同，RenderTexture在MOBA游戏中的内存占用保持在较低的水平，在2016Q3出现41.2MB的高值后，迅速回落，并稳定在25MB左右的内存占用。 8、粒子系统资源内存 严重程度：噩梦 与粒子系统的开销一致，其内存占用也在2017年呈现持续大幅上升趋势。粒子系统的内存占用主要与其内存中缓存的数量相关，对此，建议研发团队在后续研发中对粒子系统的使用进行密切关注和严格控制。 四、MOBA手游资源管理分析 在资源加载方面，AssetBundle.Load是项目中的主要加载方式，且主要集中在场景切换处。就目前的MOBA游戏而言，绝大多数项目使用的加载方式仍然是同步加载。 1）New WWW是MOBA项目中AssetBundle的主要加载方式。 2）LoadFromFile(Async)的使用在2017 Q2上大幅增加，但整体仍然较少，仅占10.5%。这主要是因为市面上仍有不少MOBA项目使用的是Unity 4.x版本所致。但如果您的项目目前是使用Unity 5.x版本开发，建议尝试升级到Unity 5.3版本以后，并通过LoadFromFile(Async)的方式进行加载。 Instantiate/Destroy和Active/Deactive调用次数较高，需要研发团队根据自身项目情况时刻注意： 1）由于Active/Deactive每次调用的CPU开销不大，且不会造成崩溃、闪退等问题，所以研发团队极易忽视这两项操作所带来的性能问题，因而出现了游戏运行1万帧Active/Deactive上万次调用的情况。因此，此处存在着很大的性能浪费； 2）Instantiate/Destroy的调用次数同样较高，但与MMORPG和ARPG游戏不同的是，Instantiate调用主要发生在场景切换处，大量GameObject在Instantiate实例化后被缓存使用，而为了保证战斗时的足够流畅，战斗过程中研发团队大多通过Active/Deactive操作来代替Instantiate/Destroy操作； 3）Destroy操作大幅高于Instantiate操作。经过进一步分析，这主要是由于当前MOBA项目中NGUI使用占比较高所致。在对NGUI制作的UI界面（比如血条等HUD）进行Deactive操作是MOBA战斗过程中较为频繁的操作，而此Deactive操作会引发UI底层Destory相关的Material操作。所以会出现Destory次数次数大幅高于Instantiate次数的情况。 五、UWA 对于MOBA手游研发团队的建议 MOBA是移动游戏研发难度较高的品类，其对于性能的严苛要求可谓达到了“寸土寸金”的地步。目前国内仍然在开发MOBA类移动游戏的，也都是技术实力与情怀兼备的团队。正因如此，MOBA游戏在很多模块中的性能表现已经较为优秀。对此，我们对于MOBA项目研发团队的优化建议如下： 1、渲染方面，Draw Call的控制技术已被MOBA研发团队所熟练掌握。随着玩家的设备质量提升，建议研发团队考虑GPU Instancing技术，该功能已经在Unity 5.5版本以后被支持，由于MOBA项目的特殊性，研发团队可以考虑将其应用在场景中的草、树木等大量重复物体重，从而进一步降低渲染模块在CPU端的开销。但是，需要注意的是，GPU Instancing的技术虽然可以降低Draw Call，但仍需要节制使用，因为其在移动设备上的GPU和能耗方面的压力可能会让你大吃一惊。 2、UI方面，与其他游戏类型一样，UI网格重建开销在未来相当长的一段时间内仍然是研发团队头痛的问题，UI优化的原则非常简单：动静分离，但真实操作起来则是非常困难。90%项目中的UI性能问题是由于动静元素没有分离导致，但没有任何两个项目的具体原因是一致的。这是UI性能优化方面非常困难的主要原因。 3、逻辑代码方面在上述报告中并没有特别谈及，这主要因为MOBA类型的项目，其在战斗时的逻辑代码开销主要为自身开销，即项目自身的AI、同步等操作，其主要包括小兵和怪物的攻击搜索、寻路操作、位置和状态的持续更新等等。对此，建议研发团队关注其AI操作的调用频率和单位开销是否合理。 4、动画模块方面，随着MOBA游戏中怪物、小兵和英雄的角色复杂程度越来越高。建议研发团队考虑通过GPU Skinning + GPU Instancing的方式缓解大量蒙皮网格在动画模块和渲染模块中的性能开销，具体做法可参见《GPU Skinning加速骨骼动画》。 5、在内存优化方面，Mono、网格和粒子系统内存占用在2017年的上升趋势非常明显，对此，建议研发团队在接下来的项目研发中密切关注这两项的内存使用。 6、资源加载方面，New WWW仍然是MOBA研发团队的主流AssetBundle加载方式，但我们建议正在使用Unity 5.x的研发团队，使用LoadFromFile(Async)的方式来对AssetBundle进行加载。对于仍然没有使用该方式的研发团队，建议查看UWA博客上的相关文档（blog.uwa4d.com），并找到对应的性能比较和分析。 7、 以上数据是我们对于MOBA手游性能数据的整体研究和趋势分析，旨在从宏观上为大家展现项目中普遍存在的性能瓶颈和研发团队容易忽视的潜在性能问题。但同样需要说明的是，优化是一个“抽丝剥茧”的过程，需要研发团队花费大量的时间和耐心去完成。UWA建议：多做测试，以数据说话，空杯心态，将经验归零。 关于UWA 由侑虎科技开发的游戏/VR应用性能优化平台，目前提供 1）性能检测与优化 2）资源检测与分析 3）UWA GOT 三大工具。同时，我们也会为大家开发更省心的功能，希望通过它们可以减少开发者反复测试定位问题的时间，从而将更多的精力集中在项目开发和解决问题中，能为大家项目研发省下的任何一分一秒，都是UWA团队的骄傲。
搞定这些问题，一个插件就够了！—UWA GOT 功能全剖析
继UWA GOT推出后，我们接到了大量的反馈，其中不乏一些令我们感动的评价和建议，在此首先感谢大家的关注和支持： 感谢如此走心的评价，鼓励亦是动力！ 读到这里，对于还不了解UWA GOT的朋友肯定多了一个问号，它究竟拥有什么力量，为何近期能在游戏圈小小地火了一波？接下来小编就为大家全面剖析UWA GOT的三大功能，并附上真实演示实例。 UWA GOT 全称 Game Optimization Toolkit，是由侑虎科技研发的本地性能测评工具。它既能方便研发团队在本地直接进行真机测试，也支持在Unity Editor中搭建本地服务器来接收和分析性能数据。整个测试过程中，研发团队能自定义测试时间和流程，几分钟后即可查看性能数据，同时还提供深度的数据分析，如脚本中的主要函数耗时、堆内存的具体分配堆栈等高级分析功能，从此为大家的项目性能又增添一份安全堡垒！ UWA GOT 目前提供 Performance Overview、Mono Memory Analysis 和 Runtime Asset Tracker三大功能。 功能一：Performance Overview 主要包括逻辑代码的CPU开销以及硬件设备等具体信息。 1、逻辑代码的CPU开销 在“Version”中选择需要查看的测试版本。 选择后，UWA将载入相应数据并进行分析和展示，主要包括CPU开销走势图、项目运行视图以及CPU耗时分析视图。 下图即为CPU耗时分析视图，从左上角可以看到，UWA将逻辑代码的CPU耗时进行总结，用户选取某一指定的函数，即可看到它在运行时的具体耗时，也能通过调整关注区域视图中的滑块，来查看重点关注区域的CPU开销。 同时还能动态调整数值的范围，方便用户进行进一步查看。 2、硬件设备信息 在“Mode”中选择“Hardware”，即可查看App运行时的硬件设备运行信息，主要包括：硬件设备的内存信息（PSS内存在项目运行时的走势）、电量、温度以及网络流量统计走势等具体信息。 上图为项目运行时，PSS内存的走势图。 功能二：Mono Memory Analysis 主要包括代码堆内存累积分配和代码堆内存泄露分析。 1、代码堆内存累积分配 在“Mode”中选择“Total”，即可查看App运行时每个函数的总体堆内存分配情况。在“Top List”中选择具体的函数名称，研发团队可以看到相应函数的具体堆内存分配情况，并且通过与图表进行交互来查看任何一帧的具体堆内存分配。 2、代码堆内存泄露分析 如下图所示，在“Top List”中选择具体的函数名称，即可看到相应函数的具体堆内存分配情况。我们在“Diff Mode”中选择“ON”，即可开启“代码堆内存泄漏分析”功能。选择任意两个柱状图，则可以快速比较两次堆内存占用的差异。通过比较差异，我们能快速定位堆内存变化的出处。 功能三：Runtime Asset Tracker 该功能主要包括资源使用情况、每帧中资源的具体使用情况、资源泄露分析以及资源冗余分析四大功能。 1、资源使用情况 在TopList中选择我们想查看的资源类型，点击资源使用走势图，即可查看每帧该类资源或某个特定资源的具体使用情况。 下图中，我们选择纹理资源类型的走势图，在面板下方马上就显示了项目运行时所有纹理资源的具体运行信息，包括：占用内存、高度、宽度、格式等，一览无遗，各种资源尽在掌控。 2、资源泄漏分析 大多数项目或多或少都存在资源泄漏的问题，但有了UWA GOT的帧比较功能，研发团队可以轻松分析是否存在资源泄露等问题。 以下图为例，我们在纹理资源中，选中第12000帧与第17700帧的资源使用情况进行比较。其中，“Max Memory”中为正值的资源表示为第17700帧中的新增资源（若存在负值即表示为第17700帧中的减少资源）。通过这种比较，即可协助研发团队快速定位具体的资源变化量和解决资源泄露等问题。 3、资源冗余分析 项目运行过程中，内存中的资源很有可能出现冗余情况。对此，建议研发团队详细查看资源数据展示界面中的“Max Count”数值， “Max Count”大于1的资源存在冗余问题的风险较高。Max Count是指项目运行过程中，某一资源在某一帧中的最大资源使用数量。 都说这么多了，是不是就差链接入手一个？ 小编特此附上入手指南，快收下~ UWA GOT 入手指南 Q1：官方是否会对UWA GOT进行维护和功能更新？官网的价格包括了之后的更新吗？ 是的，我们会不定时更新UWA GOT的新功能，并在官网和官方微信上进行说明，敬请关注。 Q2：UWA GOT目前支持什么平台？ 目前支持Android、iOS以及Windows平台，关于更多平台的支持及功能升级，我们将持续更新，敬请关注。 Q3：目前提供的入手渠道是什么？ 用户可以登录UWA官网，在下载页面（https://www.uwa4d.com/#download）进行购买，目前接受支付宝、微信和 PayPal （PayPal只适合大陆以外的用户）三种支付方式。 Q4：购买提供发票吗？ 我们提供发票，请登录UWA个人账户，进入发票系统，填写发票信息并申请开具发票。 Q5：购买了遇到问题，如何联系？ 您可以加入 UWA 技术群（793972859），这里会有UWA官方人员和更多Unity开发人员一起交流他们的问题，并分享他们的解决办法。同时也可以发邮件至support@uwa4d.com，我们将尽快与您联系。 关于UWA 由侑虎科技开发的游戏/VR应用性能优化平台，目前提供 1）性能检测与优化 2）资源检测与分析 3）UWA GOT 三大工具。同时，我们也会为大家开发更省心的功能，希望通过它们可以减少开发者反复测试定位问题的时间，从而将更多的精力集中在项目开发和解决问题中。我们将以实力和态度诠释我们对性能优化的定义：解决你的性能问题，方为“优化”。
本期我们聚集了这些话题：被自动打进AssetBundle的资源无法主动加载出来吗、Spritepacker自动划分Group、资源Ref count为空、Graphics ApI选择... 我们将从日常技术交流中精选若干个开发相关的问题，建议阅读时间15分钟，认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。 UWA QQ群：793972859 UWA 问答社区：answer.uwa4d.com 资源管理 Q1: 在打包的时候，有一部分资源是没有设置AssetBundleName的，打包的时候会和依赖它们的资源打到同一个AssetBundle包里（Unity自动完成）。在资源加载的时候，无法主动获取到这些没有设置AssetBundleName的资源。GetAllAssetNames、LoadAllAssets这些接口的返回值中都没有这部分资源。 请问，在你们看来，这种情况是Unity的设计还是Bug？如果是如此设计的话，有什么特别的意义吗？ 提供一个简单的情景，如下： １）有A、B两个Prefab，其中A上挂个脚本引用了B ２）打包的时候，设置A的AssetBundleName＝"prefab.unity3d"，B的AssetBundleName=None ３）打包，只产生prefab.unity3d这一个AB包，其中包含了A、B两个资源 ４）加载代码使用AssetBundle.LoadAllAssets()，返回的数组里只有一个资源（A） 我们刚刚在Unity 5.5.2版本上进行了一个测试，得到与题主一样的结论。 我们更加倾向于它是一种设计，而非Bug。因为Prefab B是作为一种参数被引用在A的脚本中，所以在AssetBundle中，它将以GameObject B的形式存在，但是不会存在于AssetBundle的映射表中。而对于题主的这种打包方式而言，AssetBundle的映射表中只会有一个，就是Prefab A。而AssetBundle.LoadAllAssets虽然会把GameObject A、B及其关联的资源全部加载，但其返回的Object[]内容应该就只有一个，也就是Prefab A。 所以，UWA推测，AssetBundle中在打包时是自己维护了一个map的，只有明确被设置ABName的资源才会被放入map中，也只有map中的资源才可以通过特定名称进行Load，而其关联的资源则会被打包到AssetBundle中的其他container中，是无法通过LoadAsset或LoadAllAssets API来获取到的。 此问答来自于UWA 问答社区： https://answer.uwa4d.com/question/594dc62dba16a4c31f8ca1ac 如您对该问题仍有疑问，可以转至社区进行进一步交流。 性能 Q2：UGUI自动打包图集时，有时候同一个Tag会自己打出多个Group图集，导致DrawCall增加，有什么解决方法吗？这个分Group的原理是什么？ 不少的项目都会遇到这个问题，即很多纹理打上了相同的Tag，但是却出现在了不同的Group中，类似下图，一个图集里包含了四个Group： 而产生Group的原因主要有两种： 1. 纹理的格式不同 。举例来说，有这样四张纹理格式分别为：RGB24，ETC1，RGBA32和ETC2，那么设置一样的Tag后，对应的图集就会有四个Group： 2. 纹理量太大。一个Group放不进，这个原因是容易理解的，就不解释了。 其中特别容易忽略的一点是，某些小纹理可能没有Alpha通道，导致了图集被分成两个Group，引起DrawCall的增高，这种情况下可以直接修改纹理，也可以强制设定为Aalpha通道的格式。 此问答来自于UWA 问答社区： https://answer.uwa4d.com/question/594cef012a0bce361ae401ba 如您对该问题仍有疑问，可以转至社区进行进一步交流。 性能 Q3：Gfx.ProcessCommands包含哪些行为操作？据我了解，该行为是在RenderThread中，导致该行为耗时的主要原因是DrawCall。 那么除了DrawCall还有那些行为被记录到该过程中呢？ 另外这过程耗时统计是否还包括顶点、材质贴图以及Shader等从内存到GPU的IO时间呢？ 该问题限制在OpenGL ES 2.0/3.0驱动下思考，无需考虑Vulcan/Metal等目前面向多线程的驱动。 题主所列的这些行为应该是都在里面的。因为，即使是多线程渲染，图形API的调用也需要在同一个线程中。其一，是Android系统的EGLContext一般不是线程独共享的，也就是只有一个线程能向同一个EGLContext里面发送GL指令。其二，如果使用共享的EGLContext，多个线程都能提交图形API，渲染的结果很难保证正确性。比如：如何保证线程A绑定了VBO或者Texture之后，线程B提交DrawCall时一定是它需要的呢。综上所述，我们认为这些行为应该都在一个线程里面执行的。 此问答来自于UWA 问答社区： https://answer.uwa4d.com/question/594a1e2b8a2462602c976405 如您对该问题仍有疑问，可以转至社区进行进一步交流。 性能 Q4：大家现在在工程里还是选择只使用 OpenGL ES 2.0吗？我记得以前大家都是这么做的，现在这个做法过时了吗？iOS 是否该加上 Metal？ 我们目前都是用的Auto，主要有两个原因： Metal测试下来CPU Overhead会比GLES低很多 GLES3能够有tex2Dlod支持 兼容性上来说只有实在老的机器和模拟器会fallback到GLES2，可能效果上会略差一些不过我们测试下来都可以接受。 感谢 UWA 问答社区的钱康来提供了以上回答。 我们现在快要上线的项目选的是ES3.0，iOS和Android都是选的这个，iOS选Metal的时候遇到模型显示不正常的问题，但是能力有限加上没时间没定位到原因，就统一成ES3.0了。选ES3.0还有一个原因，就是发现AssetBundle打出来的资源会比选Auto小很多。 还有就是目前我们的游戏偏重度，不指望用老手机的玩家会付费，所以放弃显卡太老的机型了。 感谢 UWA 问答社区的李先生提供了以上回答。 此问答来自于UWA 问答社区： https://answer.uwa4d.com/question/594ddec949dc1fb06ce0685f 如您对该问题仍有疑问，可以转至社区进行进一步交流。 性能 Q5：Unity Profile性能检测中，请问Ref count什么情况下可以为空？ 这说明当前fabao_suipian这个资源没有被任何脚本、资源所引用。如果之前该资源有引用，那么现在引用它的资源应该被销毁了。 比如，这个Texture之前可能被Material所引用，那么现在这个Material应该被UnloadAsset释放了。 再比如，这个资源是题主通过Resource.Load或AssetBundle.Load来加载的，然后将其缓存在一个变量中，那么当该变量被设置为null时，也会资源不再引用的情况。 所以，题主需要根据自己的情况来判断一下，这个资源是哪里加载的，具体想怎么使用。 此问答来自于UWA 问答社区： https://answer.uwa4d.com/question/594e15ecf27d373e23a1a09e 如您对该问题仍有疑问，可以转至社区进行进一步交流。 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站（answer.uwa4d.com）上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com 官方技术QQ群：793972859（仅限技术交流）
前不久UWA推出了资源检测功能之后，开发者的反应是这样的： 是这样的： 更有开发者把报告优化的成果晒给了我们：效果拔群！ 除了自动检测，反馈神速等低门槛的使用方法，开发者表示最认同的是该工具分析深度、冗余资源看得见！ 今天，沉浸在喜悦之余的我们，再为Unity 5.3版本上开发的朋友带去福音——与时俱进，我们全面支持Unity 5.x的正式版了！ 在UWA团队多年的技术支持中，常会被开发者问到：“如何减小包体大小、如何应对资源冗余，内存泄露”等在小编看来已偏形而上的问题。即便我们给出一些类似优化美术资源、注意依赖性打包机制等长篇大论，开发者在亲自优化的时候，仍需要根据具体问题具体分析。那么如何得到量身定制的解决方案，并做针对性的优化呢？ AssetBundle依赖性关系 AssetBundle之间的依赖关系是依赖关系打包的精髓所在，也是最容易出现问题的地方。依赖关系建立不当，往往会给项目运行带来极大的影响，比如资源丢失、资源冗余和内存泄露等等。正因如此，我们对AssetBundle文件的依赖关系进行了详细分析，并将其之前的详细依赖关系通过表格进行展示，以方便开发者对AssetBundle的依赖关系进行更好地管理。 如下图，表格中列出了每个检测到的AssetBundle文件，及其具体依赖的AssetBundle文件。开发者可以随时对任意AssetBundle文件、资源信息进行详细查询。 AssetBundle资源冗余 “资源冗余” 是AssetBundle文件在打包时最容易出现的问题。该问题在UWA性能诊断与优化中也常常出现。下图即是某动画片段资源在项目运行过程中出现的 “冗余” 问题。其根本原因，可直接查看相关文章《性能优化，进无止境---内存篇（下）》 在该页面中，开发者可以详细查看出现冗余资源的AssetBundle文件。点击 “含冗余资源的AB数”，则可以看到存在问题的AssetBundle文件，及其相应冗余资源的具体的信息。 由于篇幅有限，我们在此仅列举部分，更多功能（如缺失AssetBundle资源检测、脚本使用情况检测）等待开发者亲自探索。 同时，在我们的工具实现了一次次的光荣使命后，也有热心的开发者提出了以下建议： 能否将每次上传的资源包做对比？ 的确，该功能使得用户体验会更好，我们会尝试在以后的版本中提供该功能。 如果能加上资源大小的排序，就更好了。 该功能已经在Roadmap中了。 .... 感谢这些帮助UWA不断进步的使用者！看，学习总是相互的。每次和开发者的沟通中，我们从来都不仅仅是知识的给予方，我们也总能收获一些有趣的、值得深入探索的奇思妙想。 最后，UWA团队真诚希望，看到这篇文章的你，能把你们优化的同事邀请至项目中。优化大业，你从来都不是一个人在战斗；同时，也记得分享给你的任何一个开发者朋友，为了国产游戏品质的不断突破，何不再UWA（优化）一下？