最近一段时间一直在做Unity 在IOS设备上的资源优化,结合Unity的官方文档以及自己遇到的实际问题,我把自己认为一些重要的信息罗列在下面,并尽可能对将其量化,以方便更多需要做优化的朋友。
1、 角色
这是因为当角色仅有一个 Skinned Mesh Renderer 时, Unity 会 使用可见性裁剪和包围体更新的方法来优化角色的运动,而这种优化只有在角色仅含有一个 Skinned Mesh Renderer 时才会启动。
2-3 个
小于 30 个
300-1500
这是因为角色的动作大多数都是事先设定好的,并不需要经过 IK 操作来进行实时计算( Rogdoll除外),所以在模型导入时,不要将 IK 结点一起导入。
2、 静态实体
在静态实体上附加 Animation 部件虽然对结果没有影响,但却会增加一定的 CPU 开销来调用这一组件,所以尽量去掉该组件。
小于 500
尽量保证 UV 值不越界,这对于将来的纹理拼合优化很有帮助。
3、 地形
长宽均尽量小于 257 。这是因为地形太大,会造成大量顶点数据,给你的内存带宽造成一定的影响,在目前的 ios 设备中,内存带宽是非常有限的,需要尽量节省。同时,如果用 Unity 自带的地形,一定也要使用 Occlusion Culling ,因为 Unity 的刷地形工具虽然方便,但却是 framekiller ,刷过之后,你会发现 drawcall 增加的非常多。
不要超过 4 。地形的混合操作是很耗时的,应该尽量避免。能合并的纹理尽量合并。
4、 纹理
建议 png 或 tga 。不用转成 ios 硬件支持的 PVRTC 格式,因为 Unity 在发布时会帮你自动转的。
长宽小于 1024 。同时应该尽可能地小,够用就好,以保证纹理对内存带宽的影响达到最小。
建议生成 Mipmap 。虽然这种做法会增加一些应用程序的大小,但在游戏运行时,系统会根据需求应用 Mipmap 来渲染,从而减少内存带宽。
如果纹理的 alpha 通道均为 1 ,则用 RGB 的 24 位纹理来代替 RGBA 的 32 位纹理。(据说 Unity 内部会进行自动检测)
5、 光源
建议 1 个,一般为方向光。“ Important ”个数应该越小越少。个数越多, drawcall 越多。
1-2 个。
6、 粒子特效
建议小于 200 个粒子。
建议不超过 50 个。
如果可以的话,粒子的 size 应该尽可能地小。因为 Unity 的粒子系统的 shader 无论是 alpha test 还是 alpha blending 都是一笔不小的开销。同时,对于非常小的粒子,建议粒子纹理去掉 alpha 通道。
非常耗时。
7、 音频
使用 .ogg 或 .mp3 的压缩格式。
使用 .wav 和 .aif 的未压缩音频格式。
8、 相机
将远平面设置成合适的距离。远平面过大会将一些不必要的物体加入渲染,降低效率。
Unity 提供了可以根据不同的 layer 来设置不同的 view distance ,所以我们可以实现将物体进行分层,大物体层设置的可视距离大些,而小物体层可以设置地小些,另外,一些开销比较大的实体(如粒子系统)可以设置得更小些等等。
9、 碰撞
如果可以的话,尽量不用 MeshCollider ,以节省不必要的开销。如果不能避免的话,尽量用减少Mesh 的面片数,或用较少面片的代理体来代替。
10、 其他
尽可能地减少 Drawcall 的数量。 IOS 设备上建议不超过 100 。减少的方法主要有如下几种:Frustum Culling , Occlusion Culling , Texture Packing 。 Frustum Culling 是 Unity 内建的,我们需要做的就是寻求一个合适的远裁剪平面; Occlusion Culling ,遮挡剔除, Unity 内嵌了 Umbra ,一个非常好 OC 库。但 Occlusion Culling 也并不是放之四海而皆准的,有时候进行 OC 反而比不进行还要慢,建议在 OC 之前先确定自己的场景是否适合利用 OC 来优化; Texture Packing ,或者叫Texture Atlasing ,是将同种 shader 的纹理进行拼合,根据 Unity 的 static batching 的特性来减少draw call 。建议使用,但也有弊端,那就是一定要将场景中距离相近的实体纹理进行拼合,否则,拼合后很可能会增加每帧渲染所需的纹理大小,加大内存带宽的负担。这也就是为什么会出现“ DrawCall 降了,渲染速度也变慢了”的原因。
Unity 在运行时会对 static 物体进行自动优化处理,所以应该尽可能将非运行实体勾上 static 标签。
尽可能地使用 prefab 的实例化物体,以降低内存带宽的负担。检查实体的 PrefabType ,尽量将其变成 PrefabInstance ,而不是 ModelPrefabInstance 。
备注: 优化是个无止境的过程, 可优化的项目其实还有很多很多,比如脚本优化,shader优化等等,这些留待以后再慢慢添加。