UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 - 内存
type: channel
link: https://blog.uwa4d.com/tag/内存/
items: 【求知探新】分享一次查找GfxDriver内存暴涨的经历
items: 技术分享连载（九十三）
items: 技术分享连载（九十）
items: 技术分享连载（八十九）
items: FPS手游《战地先锋》性能案例精讲
items: UWA发布 | 2017 Unity手游体检蓝皮书 — MOBA篇
items: Unity优化百科（UWA 博客目录）
items: UWA发布 | 2017 Unity手游体检蓝皮书 — ARPG篇
items: UWA发布 | 2017 Unity手游体检蓝皮书 — MMORPG篇
items: 技术分享连载（七十）

【求知探新】分享一次查找GfxDriver内存暴涨的经历
type: item
date: 2018-03-28T12:57:00+03:00
description: 【求知探新】是UWA新推出的栏目。在大家做性能优化的过程中，常常会遇到一些未知的问题，在这里我们将分享研究这些问题的完整过程。当然需要说明的是，一个好的问题没有标准的答案，在此也欢迎大家来积极拍砖！ GFX内存为底层显卡驱动所反馈的内存分配量，主要由渲染相关的资源量所决定，它的大小也和项目的运行内存息息相关，所以我们在优化时也需要重点关注。本文，作者李星（联系邮箱：lx458004975@163.com）分享了项目研发过程中，由于GFX暴涨导致了内存崩溃的排查过程，值得参考。 一、问题描述 近期我们项目从Unity 5.5直接切换到了Unity 2017.3，颜色空间也由之前的Gamma切换到了Liner。为了测试切换大版本后，对游戏的FPS影响有多大，我们开始对一些战斗场景进行多人PVP的测试，然而经过几分钟后游戏闪退了，多次测试并且通过Logcat我们发现显存爆掉了。为了进一步的确认，我们切换到了Debug版本，通过Profiler发现GfxDriver撑的特别高，一般被爆掉的时候高达300MB以上。 二、问题分析 一般而言GfxDriver统计的内存其实就是Textures + Buffer（顶点和索引）的显存，这个在Unity 4源码中其实GfxDriver的统计也只是在提交Textures以及顶点和索引的使用调用这个统计宏，且Unity中文论坛中也有相应帖子解释http://forum.china.unity3d.com/thread-1091-1-1.html。 然而，我们观察发现Profiler统计的Textures + Meshes的内存远小于GfxDriver统计的内存，这就排除了因为资源管理不当没有及时释放资源导致的问题，因为一定时间后Textures和Meshes的内存已经相对稳定了。 三、问题排查 1、Auto Graphics API勾选的影响 之前依稀记得UWA官方群里面关于勾选Auto Graphics API后Gfxdriver暴涨的讨论，后来网络也搜索了下，找到了两个。 一个来自知乎： https://www.zhihu.com/question/60371399； 一个是UWA问答： https://answer.uwa4d.com/question/5a741b6fe3b569146eeaeb3a； 从这两个搜索到的帖子来看勾选Auto Graphics API后导致GfxDriver暴涨的可能性也还是比较大的，因此开发大神去掉了这个勾选，选择了OpenGL ES3，经历过漫长的打包等待后，再次测试验证，发现问题依然存在，并没有解决问题。 2、监控PSS，对Memory进行Detailed监控 在发现去掉勾选Auto Graphics API并不能解决问题后，又对其进行了勾选回去，同时我们对Memory进行Detailed监控，也并没有发现任何可疑的地方，因此我们再监控了下PSS，发现PSS的走势是随着GfxDriver的增长而增长。这个问题是因为显存爆掉而产生的，之前用Unity 5.5版本的时候就遇到过Android 6.0的机器会因为这个而闪退，而Android 7.0的机器却不会闪退，那么会不会是不同系统、不同手机而结果不一样呢？我们两台小米5，一台是Android 6.0，一台是Android 7.0的，测试都会闪退，用红米Note4来测试，发现居然不闪退，而且GfxDriver也挺高的。开始怀疑人生了，资源没问题，内存详情里面也看不出蛛丝马迹，关键是不同的手机居然还有不闪退的，会不会是Unity的Bug导致？ PS：这里有一点忽略了，其实在事后我们解决了问题后再回过头来看，在Detailed模式下进行Take Sample还是有一点踪迹可寻的，在Scene Memory项下可以看到Sprite的数量是飙升的，当时主要是Scene Memory的总内存数占用不大，与GfxDriver统计到的300MB多相差太远，而且我们Take Sample的次数也较少，同时在Simple面板可以看到Total Object Count的数量在涨，当时进入了误区，以为是Unity的Bug，因为Unity的坑有时候也有遇到嘛。 3、对测试场景的单个资源单个技能一一测试 在经历这么多尝试之后依然没有解决问题，同事开始了针对当前测试场景的每个特效、每个技能逐一单独进行排查。在经历了几天的排查之后告诉我找到了，是某一个游戏技能引起的，我立马打开编辑器运行到其场景，然后定位到其相应的角色及UI上，因此对其部分代码进行屏蔽，打包再次测试，终于有结果了，造成GfxDriver暴涨的就是这一段代码。 这段代码有两个影响点，一个是阴影，一个是Sprite的。因为在Memory Detailed模式下，我们并没有发…

技术分享连载（九十三）
type: item
date: 2018-01-03T04:00:00+02:00
description: 本期聚集了这些话题：UGUI对于emoji表情的处理、CreatefromMemory使用策略、Resource.Load加载时的内存波动、Animator采样...... 我们将从日常技术交流中精选若干个开发相关的问题，建议阅读时间15分钟，认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。 UWA QQ群：793972859 UWA 问答社区：answer.uwa4d.com 内存管理 Q1：我们用的是Unity 5.5.2，下图是红米2上测试的加载8个特效资源，峰值是46MB，然后就下落到22.6MB，这个内存波动是什么引起的，是因为Rendering Batches吗？ 按照题主提供的例子，UWA进行了测试，在Unity 5.5.2版本中的Android真机上确实复现出了这个问题。 加载4个粒子特效，红米2设备上，加载前内存： 加载时内存： 加载后内存，确实出现了Unity内存快速升高而又回落的“抖动”现象： 对此，我们又在Unity 5.6.2版本上进行了真机测试，同样是红米2： 加载前内存： 加载时内存： 加载后内存，虽然内存同样存在小幅抖动，但其抖动范围已经明显降低。 因此，建议研发团队尝试控制同一帧中Resources.Load的加载次数或者升级到更高Unity版本。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a40eaa2b319bedd3bec6d90 UGUI Q2：我们使用UGUI的Input Field，在手机上面如果用户输入系统自带的emoji表情，会导致一些问题，导致Input Field输入框显示异常，比如会出现一个问号的字符一直没法删除之类的，请问有什么办法可以过滤掉玩家输入的emoji表情？或者把emoji表情匹配成其他的字符？我现在是用正则来匹配emoji表情的unicode编码，但这样还是会出现覆盖不全的情况。 我们现在的处理方案，在inputfield上挂一个组件，采用类似代码来过滤表情符号，不过还没测试过能够完全符号所有表情符号，虽然不能过滤到所有的表情符号，但也不会报错。 public char ValidateInput(string text, int charIndex, char addedChar) { // Emoji表情 if (char.GetUnicodeCategory(addedChar) == UnicodeCategory.Surrogate) { return ‘\0’; } } 感谢 rubbyzhang提供了以上回答。 UWA试下来在Unity 5.5.5p2上也重现了该问题。但在Unity 5.6.2上没有这个问题。升级确实可能会带来风险，所以建议一种方法是用正则来匹配，网上一般也都用的这个方法。 第二种是建议可以试一试的，就是对比下Unity 5.5.5p2和Unity 5.6.2的UGUI的代码改动（主要是InputField的），尝试自己对照着修修看，然后自行编译UnityEngine.UI.dll。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a4448e47a38eea813706571 动画 Q3：Unity 4.x Animator 能否在编辑器下进行采样呢？比方说一个技能动作30帧，想知道每一帧下模型各个节点的坐标旋转缩放，该怎么办呢？ 1）可以在Animation窗口中直接看。 2）利用API： AnimationUtility.GetAllCurves或AnimationUtility.GetEditorCurve获取各节点的各属性AnimationCurve，然后取各AnimationCurve.keys中的keyframe的value。 之前UWA Blog里有两篇博客涉及到动画采样，GPU Skinning和动画文件降低精度，里面都有涉及采样部分的代码，建议题主可以去看看。 该问题来自UWA问答社区，感谢招文勇提供了回答，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a44ff2c997cacca2128b1e1 资源管理 Q4：不同项目的AssetBundle能够相互读取吗？有什么加密方式吗？不同的Unity版本对AssetBundle的兼容性如何？ 1）AssetBundle是可以互相读取的，只要Unity版本是对应的。 2）加密是跟一般的文件加密一样，但需要通过LoadFromMemory来进行加载，具体的方法网…

技术分享连载（九十）
type: item
date: 2017-12-12T04:33:00+02:00
description: 本期聚集话题：Dalvik Heap 内存过高、Unity 5和Unity 2017版本下帧率降低、如何处理Animator.Initialize警告... 我们将从日常技术交流中精选若干个开发相关的问题，建议阅读时间15分钟，认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。 UWA QQ群：793972859 UWA 问答社区：answer.uwa4d.com 内存 Q1：我们发现刚进入游戏，Dalvik Heap的内存很高，导致PSS比较高，切到后台，再切回游戏，Dalvik Heap内存减少非常多。然后我尝试使用网上说的Android调用GC的方式，System.GC，结合runFinalization。调用Runtime.getRuntime().gc()，都无法有效减少，不知道这块是否有办法有效调用一次？ 我们查到原因了，是因为我们在Android层写了一个splash，但这个splash是png的，分辨率是1920x1080，我们之前是 int splash_bg = getResources().getIdentifier(bgName, “drawable”, getPackageName()); m_BgView.setBackgroundResource(splash_bg); 这张图片在HideSplash会被处于游离状态，要等Java的GC调用后，才会回收，但实际图片按道理内存也不该涨100MB左右，我们用测试工程只有Splash和SplashVideo，发现内存并不会增长那么多，代码一模一样。后面只能解释，可能JVM后某种内存分配算法造成的，当本来比较低的情况，分配会比较少，当到达一定数量级，再分配，就会分配更大一块内存(对Android底层机制不熟) 后面我们改为先从getResources里获得BITMAP，然后给ImageView,再HideSplash时候，调用Bitmap的手动释放方法。 该问题来自UWA问答社区，感谢题主在解决后将其方法分享公开，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a2a04c27030070236a983f5 制作 Q2：我有一个MeshRenderer，它拥有两个材质，现在我想给其设置一个不同的MaterialPropertyBlocks，但据我所知，目前还没有能实现这样的办法，因为当我从Renderer中得到MaterialPropertyBlock后，我是不能指定它还能应用于某个材质了是吧？不知道大家有没有好的解决方法呢？ 是的，MaterialPropertyBlocks是以MeshRenderer为单位的，而不是以Material为单位的。只能建议题主对Mesh进行拆分，确保每个Renderer上只挂一个Material。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a263f54d99fdb2b3c628873 性能 Q3：最近项目从Unity 4 升级到Unity 5或Unity 2017时，在中低端Android机上，帧率降了10多帧，用Adreno Profiler上查了是GPU Bound。 我们游戏对帧率要求比较高， 游戏的时候必须满帧运行， 所以这个问题很明显。经过折腾，最后查出来是Unity 5 之后， 默认开启了Blit, 分辨率越高，GPU压力越大。 尤其在中低端机上，我用的是Adreno 405测试的， Unity 4能满帧， 但Unity 5或者Unity 2017最高才45左右， 简直不能忍。幸运的是，Unity 2017.2，官方终于开放了设置能禁止Blit. 但是Unity 5就没这个运气了， 根据官方的消息，他们暂时还没有计划把这个引入Unity 5.6， 具体帖子可见：https://forum.unity.com/threads/big-performance-issue-with-unity5-on-android.338847 在发现和解决问题的过程中，钱康来同学提供了不少帮助，在此感谢！开这个问题也是让大家知道下，免得像我当初摸石头过河，花太多时间折腾。 该问题来自UWA问答社区，感谢题主的无私分享，建议使用Unity 2017 或者Unity 5 版本的开发者密切注意！如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a282669a670486845f8a03d 内存 Q4：这个[Triggers RebuildInternalSta…

技术分享连载（八十九）
type: item
date: 2017-12-05T03:58:00+02:00
description: 本期聚集话题：Unity资源卸载API使用技巧、Reserved Total Unity内存的变化问题、MangedHeap.UseSize的数值一直在变化... 我们将从日常技术交流中精选若干个开发相关的问题，建议阅读时间15分钟，认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。 UWA QQ群：793972859 UWA 问答社区：answer.uwa4d.com 内存 Q1：我写了一个用例加载AssetBundle，并将多个特效Prefab实例化到场景中。连续运行了多次用例并把添加的特效对象都删除，而且切换了场景，我看到Profiler中的内存变化如下图所示： 我想咨询下： 1. Profiler里的Reserverd Unity内存比Used Unity内存高出很多是正常的吗？ 2. 如果正常的话，有办法可以回收Reserverd Unity内存吗？ 3. Reserverd Unity内存在运行完多次上述的用例后稳定在400MB，再运行一次用例可以上涨到450MB，虽然后面会回落到400MB。这样的表现也是正常的吗？ 题主这个数据是在Editor中做测试的结果吗？Reserverd比Used高出这么多确实不太合理；但如果是Editor中，那么Unity其实会做很多辅助操作，这些也确实是会占用内存的。所以，建议在真机中测试看看，看看这个差距是否会下来。但如果是在真机中，那么这个差距确实过高了，不太合理。 Reserverd Unity的内存是引擎自身管理的，一般会在后续不使用时自己降下来。 这种升高和回落是正常的，但至于是否应该这么高，请见1中的回答。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a1fde25bd7d86f726903207 内存 Q2：我想咨询下，Resources.UnloadUnusedAssets() 在卸载旧场景后加载新场景前调用好，还是在加载新场景后调用比较好呢？如果考虑内存峰值的话，我觉得是前者好，但是在UWA上看到有些文章说是加载场景后调用，所以想深入学习下。 如果题主是通过LoadLevel(Async)类似的方式来加载场景的话，那么Unity自身会在底层执行一次类似Resources.UnloadUnusedAssets的操作。所以，这时如果手动调用Resources.UnloadUnusedAssets操作，时间间隔很短，其实这个是有些重复的。因此，我们才建议在新场景加载后再调用一次。 但如果题主使用LoadLevelAdditive或其他类似的API来切换场景的话，那么Unity是不会调用Resources.UnloadUnusedAssets的，这时你再旧场景卸载后调用，其实也是很不错的选择。 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/5a1fc7dbbd7d86f726903206 渲染 Q3：是否可以认为Shader里 Blend Off和Blend One Zero是完全等价的？我在Unity的Standard Shader里看到它的混合是使用形如Blend [_SrcBlend] [_DstBlend]来动态控制，并且注意到其在StandardShaderGUI.cs里设置Opaque时就是设置的 Blend One Zero，那么是否可以认为在Shader里写Blend One Zero的话，和Blend Off是等价的？Unity会自动改变blendstate从而避免从destbuffer读取数据？ 我们在Unity 2017.1上测试了一下，发现实际上在Android平台的GLES调用中，Unity的Standard Shader的Opaque模式是在disable blend的状态下渲染的，实验如下： 设备：红米2。渲染场景是两个Standard Shader Opaque模式物体（Sphere和Cube），中间有一个Unlit Transparent的Quad： 通过Android工具查看GLES API调用发现，每一帧渲染Cube和Sphere的时候Blend都是关闭状态（上一帧结束时关掉），然后在渲染Unlit Transparent的Quad时打开： 其中，36个顶点的DC是渲染Cube，2304个顶点的DC是渲染Sphere，6个顶点的 DC是渲染quad。所以看起来Standard Shader的Opaque模式应该是glDisable(GL_BLEND)的状态下渲染的。 该问题来自UWA问答社区，如您对该问题仍有疑问…

FPS手游《战地先锋》性能案例精讲
type: item
date: 2017-09-04T04:47:00+03:00
description: 今天我们为大家带来由上海非钰数码科技的FPS手游《战地先锋》的 UWA测评报告分析。该游戏在各种档次的移动终端设备上，无论是画面表现力，还是性能开销都非常优异。在此，我们将对该款游戏的性能数据进行深度剖析，希望通过这篇文章可以让大家对移动游戏各个模块的运行效率有更为深刻的认知，并对大家的项目研发有所帮助。 一、CPU性能 该游戏在CPU占用方面的性能非常不错，下图为该游戏在红米Note2 设备上按照剧情进行游戏时的性能数据。可以看出，在红米Note2 上运行的24979帧中，超过33ms的帧数占比为4.3%，超过50ms的帧数占比为1.2%。考虑到切换场景时资源加载的开销，一款游戏如果超过33ms的帧数占比低于10%，则说明该游戏在绝大多数时刻的运行中都是非常流畅的。 通过进一步统计，该游戏的CPU性能超过了84%的红米Note2设备上的测试游戏，其能耗更是低于91%的同设备测试游戏。 其整体CPU性能的优秀表现与其各个模块的合理使用是分不开的。下面，我们就详细讲解一下其CPU性能方面的亮点之处。 1、渲染模块 通过UWA性能测评报告，我们可以看到该游戏详尽的渲染模块性能开销。该游戏在红米Note2设备上运行时的渲染模块CPU开销如下图所示。通过统计，半透明物体渲染的CPU消耗均值为1.5 ms，主要集中在 0.7~2.7ms 范围内（5%~95%）。不透明物体渲染的CPU消耗均值为1.8 ms，主要集中在 0.2~4.6ms范围内（5%~95%）。 Draw Call峰值为340，虽然峰值较高，但仅在场景切换处出现，这是因为项目在动态加载后通过代码调用StaticBatching的方式来合并Draw Call，所以可以看到Draw Call数量在进入场景后迅速回落。同时，Draw Call数量主要集中在 48~179 范围内（5%~95%），属于合理范围之内。 下图为该游戏在红米Note2上的具体CPU性能堆栈。可以看到，该游戏在红米Note2上无论是不透明开销还是半透明开销均处于较低水平，这得益于研发团队对于场景模型、蒙皮网格和UI的控制十分得当。 美中不足的是Shader.SetPass稍高，这主要是渲染模块中RenderState的切换较为频繁所致，对此，建议大家对场景中的Material数量进行控制，具体可以参考：《使用MaterialPropertyBlock来替换Material属性操作》 2、UI模块 该游戏在红米Note2设备上运行时的UI模块CPU开销如下图所示。该游戏使用UGUI作为UI界面的解决方案。经过统计，UI模块总体的CPU占用均值为1.9ms，主要集中在0.1~3.6ms范围内（5%~95%），属于合理范围之内。 其均值高于70%的行业数据，这是因为该项目使用的是Unity 4.7版本进行开发，该Unity版本中，UGUI并没有像Unity 5.3版本以后将部分拼合操作放到子线程中进行。在这一点上，Unity 4.x的UGUI性能较之5.3+版本确实要多一些性能上的开销。堆内存平均每帧分配为5.5B，仅高于5%的行业项目，这说明该游戏UI界面的制作及UI重建的影响范围非常合理。目前，UWA推荐UGUI模块中，平均每帧堆内存分配尽可能控制在2KB以下。 从下图中可以看出，Canvas.SendWillRenderCanvases在不同的运行时刻均出现CPU高值，但通过运行截图可以看到，其共同特点是CPU耗时高值均发生在画面底层的UI选人界面出现时。因此，该UI界面的出现或相关操作极有可能是引发Canvas.SendWillRenderCanvases CPU过高的原因，建议研发团队对该界面进行进一步检测。 3、动画模块 在UWA测评报告中，该游戏运行时的动画模块CPU开销如下图所示。 可以看出，除进入场景时出现CPU高值外，其在战斗副本中的CPU开销均控制在较低水平。Animator.Update的CPU均值为1.8ms，主要集中在0.1~3.4ms区间内，其性能较为优秀，高于28%的行业项目。同时，MeshSkinning.Update的CPU均值为1.8ms，主要集中在0.1~3.4ms区间内，高于21%的行业数据。 同时，经过进一步检测发现，其进入副本时的CPU高值均为lhAnimatorEvent.OnEventCallback回调函数所致，具体的CPU耗时堆栈如下图所示。通过此堆栈可知，其耗时主要为UI界面的加载耗时，且进一步通过资源管理信息可知其主要开销为luaUI_PK(Clone)的Active操作和luaUI_Hall(Clone)的Deactive操作所致。因此，建议研发团队可进一步检测该UI的制作是否合理，并对其进行完善。 4、GC调用 该研发团队对于GC调用频率控制得非常出…

UWA发布 | 2017 Unity手游体检蓝皮书 — MOBA篇
type: item
date: 2017-08-31T05:14:00+03:00
description: 过去的一年，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…

Unity优化百科（UWA 博客目录）
type: item
date: 2017-08-09T18:01:00+03:00
description: Hello, 各位Unity开发者，无论您是正用着UWA的工具、还是阅读着UWA的相关技术文章亦或是在UWA博客中寻找一个问题的解答，我们都倍感荣幸能和你在此相遇。本篇可以说是UWA产品服务的向导，认真读完它，您会了解UWA究竟是做什么的，并且如何利用UWA提供的资源和工具。在与UWA的日益接触中，您会发现它不仅能为你们项目的性能保驾护航，还能少走很多弯路，缩短优化的时间。 Part 1. 优化工具 Q：UWA提供哪些可以快速提升性能的工具？ 这个要从UWA的定义说起，UWA由侑虎科技开发的游戏/VR应用性能优化平台，目前提供 1）线上性能测评 2）UWA GOT 3）UWA GOT Online 三大工具。下面我们将分别介绍。 一、线上性能测评 1、性能检测与优化 通过真人真机对项目测试，提供针对性的性能报告和优化方案，既能从宏观上分析项目运行时的整体趋势，包括总体CPU性能、GC调用频率和引擎各模块性能等，也能从微观上深入剖析内存管理、资源使用以及逻辑代码在运行时的效率瓶颈。研发团队通过对报告提供的方案进行针对性的优化，能在短期内提升项目的运行效率。 入手方法：该服务主要通过在UWA官网上提交项目的测试包（apk、ipa等，无需工程源码）来完成。由UWA工作人员测试分析后，会提供针对该项目的性能报告和分析建议，可以在此参考报告demo。 该工具分为免费版和收费版，免费版一个月可以使用一次。强烈推荐大家来试试免费版哦！ 2、资源检测与分析 反馈资源的打包情况，包括具体包含的资源情况、详细的依赖关系和资源的冗余程度等。用户通过优化报告指出的冗余问题来实现减小包体、减小内存并提升加载速度的目的。 入手指南：用户在UWA官网上传AssetBundle包（无需游戏包），一旦上传，UWA将自动开启检测并返回结果，一般时长在30分钟以内（视AB包体量而定），可以在此参考报告demo。 该工具永久免费使用，无使用次数限制。 二、本地性能测试工具：UWA GOT UWA GOT 全称 Game Optimization Toolkit，是由侑虎科技研发的本地性能测评工具。它既能方便研发团队在本地直接进行真机测试，也支持在Unity Editor中搭建本地服务器来接收和分析性能数据。整个测试过程中，研发团队能自定义测试时间和流程，几分钟后即可查看性能数据，同时还提供深度的数据分析，如脚本中的主要函数耗时、堆内存的具体分配堆栈等高级分析功能，从此为大家的项目性能又增添一份安全堡垒！ 具体功能说明：戳此传送门 入手指南：戳此传送门 价格：RMB399，包括维护和更新 三、UWA GOT Online UWA GOT Online是基于其本地测评模式上的线上同步功能，研发团队可以将本地测评的数据快速同步到UWA官网，生成在线测评报告。除了“本地化”和“快”这两大天然优势，我们目前提供了四大性能检测模式：总体性能检测、Mono堆内存分析、运行时资源检测和Lua性能分析来满足大家的优化需求。 具体功能说明：戳此传送门 入手指南：戳此传送门 Part 2. 干货大全 一、引擎把握篇 性能卡顿、内存泄露、资源冗余...这些开发中遇到的疑难杂症大部分都能在这里找到解决方法，它们无不通过大量的项目深度优化和周而反复的测试验证。如果你想避开一些不必要的坑，请务必啃下这些硬货！ 1.1 Unity性能优化进无止境——CPU篇 从渲染、UI、加载等几个重要维度分析了目前大部分项目中存在的CPU性能问题和解决方案 1.2 Unity性能优化进无止境之内存篇（基础篇） 谈优化必谈内存，该文深入浅出地分析了Unity项目的内存占用 1.3 Unity性能优化进无止境之内存篇（进阶篇） 内存泄露、Mono无效堆内存、资源冗余...你关注的内存问题都在这里！ 1.4 AssetBundle打包机制详解（5.x） （4.x 版本的API接口有所差别，请看这里） 1.5 AssetBundle内存管理机制 AssetBundle真是个绝妙的设计，但是想说爱你不容易！ 1.6 Profiler中常见的高CPU耗时函数 1.7 代码热更新（dll反射） 亘古不变的话题了 1.8 加载模块详解（纹理篇） 加载龟速？是时候来点加速度了！ 1.9 加载模块详解（网格篇） 1.10 加载模块详解（Shader篇） 1.11 加载模块详解（动画资源） 二、提升：工欲善其事，必先利其器 在这里不仅有效果拔群、性能出众的插件帮助大家省心省力，也有卧虎藏龙的民间高手抛钻引玉给大家分享自己的优化技巧。 1、UI相关 2.1.1 UGUI 降低填充率技巧两则 2.1.2 如何优化UGUI的ScrollRect 2.1.3 UGUI表情系统解决方案 2.1.4 UGUI 文本多语言方案 2、制作相关 2.…

UWA发布 | 2017 Unity手游体检蓝皮书 — ARPG篇
type: item
date: 2017-08-01T04:40:00+03:00
description: 接上期UWA 发布的2017 Unity手游体检蓝皮书MMORPG篇，本期我们将深度剖析ARPG的游戏性能发展情况。此份蓝皮书收集了提交到www.uwa4d.com上的所有项目，我们从总体性能数据、引擎各模块开销、内存占用等方面进行了汇总分析，呈现Unity手游行业现状。 这是侑虎科技第275篇原创文章，欢迎转发分享，未经官方授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。（QQ群：793972859） 报告目录： 一、ARPG手游总体性能开销分析 二、ARPG手游CPU模块性能开销分析 三、ARPG手游内存模块性能开销分析 四、ARPG手游资源管理分析 五、UWA对于ARPG手游研发团队的建议 一、ARPG手游总体性能开销分析 iOS设备的CPU性能普遍高于Android设备，Android设备的CPU均值主体范围为12.4~66.2 ms，iOS设备的CPU均值主体范围为7.0~57.5 ms。 我们选择了测评次数最多的四款机型来进行统计，这四款机型分别是红米2、红米Note2、华为6Plus和三星S6。 1）大部分ARPG手游在中低端设备的性能开销较高，在Android设备上，CPU耗时集中在17~50ms区间，而在iOS设备上，CPU耗时集中在33ms以内。 2）相较2016年同期，2017 Q2 ARPG手游在低端设备上的CPU开销均值增长5.8 ms。 无论是高、中、低端的Android设备，渲染、UI、加载/代码都是需要研发团队重点关注的，它们的消耗总和占了总开销的80%。 下面我们就来具体分析这些主流模块的开销情况。 二、ARPG手游CPU模块性能开销分析 1、渲染模块 严重程度：地狱 为了能够更好地反映出各个性能参数的整体使用情况，我们统计了每种性能参数的主体使用范围，其范围区间是[5%~95%]，以下数据中P5代表5%，P95代表95%。 在Draw Call使用上，ARPG手游的使用程度略低于MMORPG手游，且对Draw Call的控制同样较高，UWA建议Draw Call占用的P95 < 200，76.3%的项目可以将其控制在这个范围内。 1）ARPG手游的场景渲染三角形面片数量普遍较高。且设备性能越高，数量峰值越高。经过统计，在中低端设备中，46.5%的项目能将渲染三角形面片数控制在100K以下。 2）ARPG游戏的场景复杂程度明显低于MMORPG游戏，渲染面片峰值要比MMORPG手游平均低50K。同时，虽然2016 Q4和2017 Q1渲染面片数量大幅上升，但2017 Q2开始回落趋势较为明显。 Graphics.Bilt操作平均每次调用的CPU耗时主要分布在: 0.1~8.5ms。该项CPU开销在低端设备上的上升趋势较为明显，但在2017 Q1大幅下降。这主要是因为，在2017 Q1后，ARPG项目普遍开启了多线程渲染功能。 2、UI模块 严重程度：地狱 使用NGUI作为UI解决方案的项目占据了较高的比例，但从趋势上来看，UGUI从2016 Q3开始，增速非常明显。通过进一步分析，我们发现近大半年来的新ARPG手游中，使用UGUI的项目显著增加，从而大幅提升了UGUI在ARPG项目中的使用占比。 下面我们将分别说明NGUI和UGUI的CPU耗时和堆内存占用情况。 UI模块的性能开销依然很高，也是我们统计中的第二大性能杀手。在中低端设备上，超过90%的研发项目在UI端都面临较为严重的性能问题，主要体现方面与MMORPG游戏类似，功能界面复杂、同一时刻需要更新的Panel多等。但ARPG的平均耗时要略低于MMORPG，这是因为ARPG主要仍以推图形式为主，其在战斗副本中的玩家是预先固定的，大量玩家同屏打怪的情况很少出现。 经统计，NGUI中堆内存每10000帧分配的主体范围为 6.0~81.7 MB，UGUI中堆内存每10000帧分配的主体范围在12.3 MB以内。从堆内存分配来看，UGUI远低于NGUI。 3、逻辑代码 严重程度：噩梦 1）GC触发频率很高，是造成卡顿的主要原因之一，目前只有12.5%的项目可以将GC的触发频率控制在1000帧/次以上。 2）在2017年GC平均耗时趋势虽有所上升，但相比于2016年已经大幅降低。 1）Instantiate实例化操作平均每次调用的CPU耗时主要分布在: 1.2~43.5 ms，且主要集中在10ms以内。 2）Instantiate实例化耗时在2017 Q2之后大幅下降，这说明越来越多的研发团队开始重视项目运行时的资源管理。 Shader.Parse 操作是比较突出的性能杀手，目前平均每次调用的CPU耗时主要分布在 4.4~145.2ms。但随着越来越多团队了解该项的耗时特性后，该项的CPU耗时呈现出较为明显的下降趋势。 4、动…

UWA发布 | 2017 Unity手游体检蓝皮书 — MMORPG篇
type: item
date: 2017-07-19T04:52:00+03:00
description: 正值UWA成立两周年之际，借着China Joy蓄势待发之势，UWA发布2016-2017年Unity手游性能测评数据分析蓝皮书，希望能为游戏行业的从业人员提供详实的信息和针对性的建议。 此份蓝皮书收集了提交到www.uwa4d.com上的所有项目，我们从总体性能数据、引擎各模块开销、内存占用等方面进行了汇总分析，这呈现Unity手游行业现状。 这是侑虎科技第269篇原创文章，欢迎转发分享，未经官方授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。（QQ群：793972859） 报告目录： 一、MMORPG手游总体性能开销分析 二、MMORPG手游CPU模块性能开销分析 三、MMORPG手游内存模块性能开销分析 四、MMORPG手游资源管理分析 五、UWA对于MMORPG手游研发团队的建议 一、MMORPG手游总体性能开销分析 iOS设备的CPU性能普遍高于Android设备，Android设备的CPU均值主体范围为14.4~73.6 ms，iOS设备的CPU均值主体范围为9.2~43.5 ms。在Android设备上，CPU耗时集中在17~50ms区间，而在iOS设备上，CPU耗时集中在33ms以内。 我们选择了测评次数最多的四款机型来进行统计，这四款机型分别是红米2、红米Note2、华为6Plus和三星S6。 1）大部分MMORPG手游在中低端设备的性能开销较高，大于33ms的耗时占比范围在60%~70%。 2）精品化过程中的MMORPG手游在低端移动设备上的CPU开销明显增大。相较2016年同期，2017 Q2 MMORPG手游的CPU开销均值增长超过50%。 无论是高、中、低端的Android设备，渲染、UI、加载/代码都是需要研发团队重点关注的，它们的消耗总和占了总开销的80%。 下面我们就来具体分析这些主流模块的开销情况。 二、MMORPG手游CPU模块性能开销分析 1、渲染模块 严重程度：地狱 为了能够更好地反映出各个性能参数的整体使用情况，我们统计了每种性能参数的主体使用范围，其范围区间是[5%~95%]，以下数据中P5代表5%，P95代表95%。 MMORPG手游的Draw Call数量普遍较高，且设备性能越好，数量峰值越高。这主要有以下几方面原因： 1）研发团队普遍开始针对不同机型来制定自适应的渲染LOD策略，主要包括模型LOD和Shader LOD等。 2）除LOD外，研发团队同样会对一些渲染效果进行有针对性的设置，最常见的是阴影的处理，高端机上开启实时阴影，而低端机上则通过较为简单的阴影面片或Projector来处理。另外，水体模拟也越来越多地在项目中被使用，高端设备上开启水面反射效果，也会增加一定量的Draw Call。 但就目前数据表明，研发团队已经开始有意地对Draw Call进行控制，UWA建议Draw Call占用的P95 < 200，72.3%的项目可以将其控制在这个范围内。 1）MMORPG手游的场景渲染三角形面片数量普遍较高。且设备性能越高，数量峰值越高。经过统计，在中低端设备中，40.4%的项目能将渲染三角形面片数控制在100K以下。 2）场景复杂程度明显增加，虽然2017 Q2数量有所回落，但相较于去年同期，仍然增幅33%。同时，较高的渲染面片数量也大幅增加了中低端设备的GPU渲染压力和耗能压力。 Graphics.Bilt操作平均每次调用的CPU耗时主要分布在: 0.1~5.1ms。与Instantiate开销类似，该项CPU开销在低端设备上的上升趋势较为明显，但在2017 Q2大幅下降。这主要是因为，在2017 Q1后，MMORPG项目普遍开启了多线程渲染功能。 2、UI模块 严重程度：地狱 使用NGUI作为UI解决方案的项目占据了相当高的比例，NGUI目前仍然是MMORPG研发团队对于UI系统使用的主要解决方案。MMORPG是目前手游中工程技术难度最为复杂的游戏品类之一，对于UI模块的选择，大多数团队仍然倾向于从稳定性和把控性两方面出发，这也是NGUI占比持续较高的主要原因。 下面我们将分别说明NGUI和UGUI的CPU耗时和堆内存占用情况。 UI模块的性能开销依然很高，也是我们统计中的第二大性能杀手。在中低端设备上，超过90%的研发项目在UI端都面临较为严重的性能问题，主要体现在以下几个方面： （1）MMORPG游戏的界面复杂，功能多（技能、背包、角色、任务、商城等），数量大（血条、名称、飘字等HUD）。 （2）同一时刻存在大量需要更新的Panel，比如，移动中血条等HUD、NPC不断更新的提示icon、面板中（任务、首充等）的提醒动画、聊天框和弹幕中随机出现的滚动文字等。 以上情况都是MMORPG项目研发团队每天面对的主要UI问题，可能一个Widget的…

技术分享连载（七十）
type: item
date: 2017-07-04T07:25:00+03:00
description: 本期我们聚集了这些话题：Physics性能开销、iOS设备上的ZFighting、AssetBundle资源冗余、UI性能优化... 我们将从日常技术交流中精选若干个开发相关的问题，建议阅读时间20分钟，认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。 UWA QQ群：793972859 UWA 问答社区：answer.uwa4d.com 物理模块 Q1：在游戏里没有使用物理（Physics)相关功能时，怎么把物理相关的性能消耗降到最低？ 我们游戏里完全没用到物理相关的功能，只是因为需要做点击碰撞检测，所以GameObject上需要加上BoxCollider组件，但是Profile时会时不时看到Physics.Processing的消耗有点高，也不算非常高，但是理论上如果完全没用物理相关功能的话，总感觉这部分消耗是可以完全干掉的，对于Profiler中Physics模块中给的几个统计不太清楚是怎么计算的，目前使用的Unity版本是5.3.6f1版本。 就我们目前的分析来看，在Unity5.4版本之前，物理模块是会每帧都运行的。而在Unity5.4版本之后，如果没有使用任何物理相关的功能时（Rigidbody、CharacterController、Rogdoll、Cloth模拟等等），物理模块会被关闭。所以，就你的问题而言，物理模块的开销只能降低，而不能完全消除。 对于物理模块的开销，我们建议从宏观上进行了解，当你的项目完全没有使用物理模块时，那就需要从它的调用次数入手了。 Physics.Processing调用耗时： Physics.Processing调用次数： 可以看到，很多时候，该函数的CPU耗时其实并不是物理开销过高，而是调用次数过多。这主要是因为Unity 5.x默认设置的Fixed Timestep为0.02，Maximum Allowed TimeStep为0.333。也就是说，物理模块每20ms更新一次，所以如果某一帧很卡（200ms），那么物理模块会被调用10次，这样耗时就直接上去了。而0.333表示如果该帧CPU开销超过333ms了，那么就不会再调用物理模块，所以上图中调用次数中最大是17次。 所以，如果想进一步降低物理模块的开销，在完全没有使用物理的情况下，可以将Fixed Timestep设置为0.05或0.1均可，降低它被调用的频率。同时，尽可能优化其他模块耗时，让每帧的总体耗时尽可能降低。另外，需要注意的是，修改Fixed Timestep也会影响FixedUpdate的调用，在修改之前一定要检测项目中是否有使用FixedUpdate。 关于Contacts、Rigidbody、Collider的说明和推荐值，在UWA Tips中均有详细的说明。同时，也可查看如何读懂UWA报告——物理篇 。 此问答来自于UWA 问答社区： https://answer.uwa4d.com/question/595351860ac5cef316b72ea1 如您对该问题仍有疑问，可以转至社区进行进一步交流。 资源管理 Q2：Unity官方半透明Shader代码在iOS上运行出现问题，参考官方文档（https://docs.unity3d.com/Manual/SL-CullAndDepth.html）中Transparent shader with depth writes写了一个半透明的Shader，在所有iOS设备上都出现类似ZFighting的错误，在XCODE上看了一下，大致定位是深度写入/读取出现了问题。 正常情况 有问题的情况 环境如下： Unity4.7.1 f1 graphics Api opengles3.0 测试设备：iPhone5s、iPhone 6、iPhone 6s. 同样的代码在Android设备上没有问题。 ios设备上将Graphics API 设置为OpenGL ES 2.0 和metal在显示正常。 同样的代码在Unity5.3.8上graphics ApI OpenGL ES 3.0 编译到iOS设备上显示正常。 请问是什么问题导致的呢？ 第一个Pass预写深度，第二个Pass比较深度LessEqual，硬件差异以及图形API差异，是很难保证第二个Pass比较深度时Equal的。 是否可以手动设置一个深度偏移量来避免这个问题，相关文档可以参考： https://docs.unity3d.com/Manual/SL-CullAndDepth.html。 此问答来自于UWA 问答社区，目前题主反馈已经得到解决，特此感谢 jim 提供的回答。 https://answer.uwa4d.com/question/5951d21d96a4c14c505c478…