抛砖引例
打开动画模块的界面,我们可以看到更详细的性能数据,下图所示的是某MMO手游在红米2上的性能表现:
从报告中可以看到,该项主要展示项目运行过程中的 “动画片段数量峰值”、“Animator.Update CPU均值”、“Animation.Update CPU均值” 和 “蒙皮网格更新CPU均值”。其中 Animation.Update 和 Animator.Update 分别表示Unity引擎两个不同动画模块的性能开销。前者对应Unity老版本的动画系统,后者对应Unity新动画系统Mecanim。
在这几个指标之后展示的是蒙皮网格更新的CPU耗时、Animator.Update CPU和Animation.Update CPU耗时,如下图所示。
关于这两个函数的耗时分布,小编提醒大家一定要查看“分析 & 建议”中主体范围(5%~95%)的数值,一般建议主体范围的CPU开销均小于3ms。
尽可能使用Mecanim
这里我们先要说明下:在UWA做过的大量性能优化案例中,发现目前使用Unity老版本动画系统的研发团队仍然不在少数。对此,我们建议尽可能使用Mecanim来作为项目的动画模块解决方案。因为Mecanim动画系统主要有以下几点优势:
- Mecanim动画系统的多线程计算性能较之老版本的单线程计算性能要高;
- Mecanim动画系统可以对GameObject开启 “Optimize Game Object” 选项。该选项为Unity引擎在4.3版本中加入的新功能,旨在优化Mecanim动画系统的底层计算开销。开启该选项,Animator.Update和MeshSkinning.Update的CPU占用均存在一定程度的降低;
- Mecanim动画系统的Retargeting功能可以让多个不同的角色使用同一套的AnimationClip资源,比如主城中的NPC角色,其大部分共性动画可尝试使用一套Idle、Wave等动画片段,从而进一步降低动画资源的内存开销;
- Unity引擎已经不再对老版本动画系统进行维护。
优化支招
动画模块的开销主要来自于MeshSkinning.Update(蒙皮网格每帧更新)和Animation.Update and Animator.Update(骨骼动画的更新开销)两个函数。关于动画模块的优化,小编给大家支几招:
研发团队在尽可能保证动画效果的同时,对模型的网格进行简化,建议尝试使用Unity Asset Store中的SimpleLOD插件来对骨骼蒙皮网格进行简化;
关于MeshSkinning.Update, 一般来说该值的大小取决于蒙皮网格(Skinned Mesh)的面片数和骨骼数。所以如果该值过高,我们的建议是减面。同时我们建议开发团队勾选“GameObject.Optimize”,该方法是将fbx生成的GameObject的层级关系移除,使动画系统不用每帧再去更新这些骨骼节点(GameObject)的Transform,因此能一定程度上降低CPU开销,此优化选项默认是关闭的),该方法特别适合于在配置较低的手机上运用骨骼角色多的情况。
现在项目对于同屏角色数量的需求越来越大。但是为什么有的项目在红米2上跑30个角色也很卡(一千面、两千面的模型),别的项目却能在同样低端的机型上流畅跑上几十个小兵(甚至七八十个)呢?他们很可能用了SkinnedMeshRenderer.BakeMesh。其原理是将一个蒙皮动画的某个时间点上的动作,Bake成一个不带蒙皮的Mesh,从而可以通过自定义的采样间隔,将一段动画转成一组Mesh序列帧。而后在播放动画时只需选择最近的采样点(即一个Mesh)进行赋值即可,从而省去了骨骼更新与蒙皮计算的时间(几乎没有动画,只是赋值的动作)。整个操作比较适合于面片数小的人物,因为此举省去了蒙皮计算。其作用在于:用内存换取计算时间,在场景中大量出现同一个带动画的模型时,效果会非常明显。该方法的缺点是内存的占用极大地受到模型顶点数、动画总时长及采样间隔的限制。因此,该方法只适用于顶点数较少,且动画总时长较短的模型。同时,Bake的时间较长,需要在加载场景时完成。我们之前测试在红米2上跑了100个不到300面的角色,非常流畅。特别推荐下:该方法比较经典的适用场景为MOBA游戏中的小兵。
控制场景中具有Animator Controller组件的GameObject,建议通过调整其Culling选项来降低视域体或一定范围外的动画组件更新。
原文出处:侑虎科技
本文作者:admin
转载请与作者联系,同时请务必标明文章原始出处和原文链接及本声明。