Unity3D优化
一、 CPU
1、 DrawCalls
DrawCall优化的主要思路就是每个物体尽量减少渲染次数,多个物体最好一起渲染。主要优化方案:
(1) 使用DrawCallBatching即批处理。Unity运行时可以将一些物体合并,从而用一个描绘调用来渲染。
DrawCall本身分为两种:
a. 静态批处理:只要这些物体不移动并且拥有相同的材质,静态批处理允许对任意大小的几何物体进行批处理操作降低描绘调用。只需要在Inspector中勾选static复选框即可。
b. 动态批处理:Unity3D自动处理。约束条件:
[1]仅支持小于900顶点的网格物体;如果着色器使用顶点位置、法线、UV值三种属性,那么只能处理300顶点以下的物体;如果使用顶点位置、法线、UV0、UV1和切向量,只能处理180顶点以下的物体;
[2]统一缩放的物体不会和非统一缩放的物体进行批处理;
[3]使用不同材质的实例化物体会导致批处理失败;
[4]拥有lightmap的物体含有额外的材质属性,不支持动态批处理;
[5]多通道的shader会妨碍批处理操作;
[6]预设体的实例会自动的使用相同的网格模型和材质。
(2)通过把纹理打包成图集尽量减少材质的使用
(3)尽量少的使用反光、阴影之类的效果,减少渲染次数
2、物理组件
a.设置一个合适的Fixed TimeStep;
b.尽量不要使用网格碰撞器(mesh collider)。
3、GC 管理的是Mono的托管堆(引用类型),优化:
a.字符串连接的处理;
b.尽量不要使用foreach,而是使用for。Foreach涉及迭代器,每次循环所产生的迭代器会带来24bytes的垃圾
c.不要直接访问gameobject的tag属性,访问物体的tag属性会在堆上额外分配空间,使用go.CompareTag()判断tag属性;
d.使用池实现空间的重复利用,避免频繁的分配回收;
e.最好不用LINQ的命令,因为他们会分配临时的空间,也是GC收集的目标;另外不用LINQ的原因就是他可能在某些情况下无法很好的进行AOT编译,可能涉及泛型类。
4、代码优化
a.以物体的transform组件为例,应该只访问一次,然后将它的引用保留,而非每次访问都去访问;
b.不要频繁使用GetComponent,尤其是循环中;
c.善于使用OnBecameVisible()来控制物体的update()函数的执行以减少开销;
d.使用内建数组,比如用Vector3.zero而不是new Vector3(0,0,0);
e.对于方法参数的优化,善于使用ref关键字,避免复杂的值类型的参数的复制。
二、GPU
1、减少绘制数目(减少顶点数量,简化计算复杂度)
(1)尽量少的材质,更易于批处理;
(2)使用纹理图集
(3)如果使用了纹理图集和共享材质,使用Renderer.sharedMaterial代替Renderer.material。sharedMaterial效率更高,无论如何操作材质的属性,内存中只占用一份;而material每次更换属性是unity会new一份新的material作用于它,直到Application.LoadLevel()或者Resources.UnloadUnusedAssets()的时候才会释放内存。所以material就有可能会造成内存泄漏。但在编辑器模式下,使用sharedMaterial会导致本地的.material文件修改。如果使用SVN管理,会发现文件都是红色的叹号,所以可以根据平台设置material的获取方式public static Material GetMaterial(Renderer render)
{
#if UNITY_EDITOR
returnrender.material;
#else
returnrender.sharedMaterial;
#endif
}
(1) 使用光照纹理(lightmap)而非实时光照;
(2) 使用LOD
(3) 遮挡剔除(Occlusion culling)
(4) 使用mobile版的shader,更简单。
2、 优化显存带宽(压缩图片)
(1) OpenGLES2.0使用ETC1格式压缩等;
(2) 使用MipMap:MipMap中每一个层级的小图都是主图的一个特定比例的缩小细节的复制品。虽然消耗内存,但是为了图片渲染的质量,这种方式更推荐。
三、内存优化
1、U3D内部内存
2、Mono托管内存:缓解GC调用次数优化引用类型使用;针对AssetBundle的使用,Unity5.3后增加了LZ4压缩格式,虽然LZ4相对于LZMA格式压缩比一般,但解压缩的时间相对要短;所以打bundle时使用LZ4压缩格式,运行时需要加载AssetBundle对象时,使用LoadFromFile方法进行加载,不会产生额外的内存。这样做的好处是:即可以将AssetBundle文件压缩,又可以兼顾加载速度,且节约内存。