Bootstrap

Unity 性能优化总结

影响性能的因素

造成游戏性能瓶颈的主要原因分成以下几个方面:
(1)CPU
1.过多的 draw call
2.复杂的脚本或者物理模拟
(2)GPU
1.顶点处理
过多的顶点、过多的逐顶点计算
2.片元处理
过多的片元(既可能是由于分辨率造成的,也可能由于overdraw 造成的)、过多的逐片元计算。
(3)带宽
1.使用了尺寸很大且未压缩的纹理
2.分辨率过高的帧缓存

针对上面的内容会涉及的优化技术:
(1)CPU 优化
1.使用批处理技术减少 draw call 数目
(2)GPU 优化
1.减少需要处理的顶点数目
优化几何体、使用LOD及遮挡剔除
2. 减少需要处理的片元数目
控制绘制顺序、警惕透明物体、减少实时光照
3. 减少计算复杂度
使用Shader的LOD技术、代码方面的优化
(3)节省内存带宽
1.减少纹理大小
2.利用分辨率缩放

可以利用Unity提供的一些渲染分析工具来实现

一、综合优化

1、降低屏幕分辨率尤其是在android平台对性能提升很大。可以有效缓解gpu的压力。

2、做好资源异步加载,实现一个实例化队列,可以很大程度上减少卡顿。

3、做好超量的模型和特效屏蔽,可以有效减轻cpu压力。

4、善用工具。比如Unity Profiler、Snapdragon Profiler等,针对性的对性能瓶颈进行优化。

5、玩家头顶血条的HUD要使用3D的,而不是UGUI。否则同屏玩家数量很多的时候Mesh合并开销很大。

6、UI上使用TextMeshPro。可以很大程度上缓解UI打开卡顿的问题。描边、阴影开销很低。

7、控制帧率。现在高刷新率的手机非常多。不要直接使用VSyncCount控制帧率了。否则在120hz刷新率的手机上vSyncCount=1会有120fps的帧率。直接使用targetFrameRate=30来设置帧率。

8、利用分辨率缩放,具体可参考设置屏幕分辨率

二、优化的经验

(一) UI的性能优化

1、每个图片材质都会产生一个dc, 只有通过打包图集,才能合并dc,。同个图集内的图片,dc都为1。不同图集渲染顺序的交叉会产生额外dc,所以界面尽量按图集整理UI顺序

2、实现一个高效率的 FindChlid 函数。因为在写UI的时候查询控件对象是非常常见的操作。如果不做优化,使用 gameObject.name == “xxx” 来做比对的话,可能会产生很多的GCAlloc。

3、血条的减少动画之前是Image和DOTween来实现的。后面修改为shader实现。(坐标计算)

4、小地图用shader实现指定位置的图片渲染,而不是RectMask2D,可以减少overdraw。因为RectMask2D是使用alpha=0来实现裁剪的。

5、小地图的玩家标识,聊天界面,都添加Canvas,目的是动静分离。

6、UGUI的合批规则是自动计算元素的层级。先排除掉active=false,使用scale=0或Canvas Group=0

(二) 场景的性能优化

1、要勾选StaticBatch,但是不能滥用有color、uv3的,顶点超过4000个以上的,数量超多,但是同屏显示不多的模型。这些都不应该勾选StaticBatch。否则会导致包体积明显增大。因为StaticBatch会把模型都build到场景的ab包内。

2、避免模型和贴图勾选 readable选项。这个可以在模型和纹理导入的时候做设置。

3、对于多个模型使用共享材质,应用Renderer.shareMaterial 来保证修改的是和其他物体共享的材质,

4、使用动态批处理时需注意顶点属性规模(超900顶点)、保证指向光照纹理中的同个位置、多Pass的shader会中断批处理(前向渲染中,需要使用额外的Pass为模型添加更多的光照,确保模型不会被动态批处理)

(三) 一般优化

1、按ID寻址属性。比如 Animator、Shader都有对应的接口。Animator.StringToHash。Shader.PropertyToID。

2、减少矢量和四元数的数学计算。控制运算顺序。尽可能不要使用分支语句和循环语句

3、隐形颜色字符串转换的时候 (#RRGGBBAA),使用一个 ColorUtility 的API会更加高效,且可以避免GCAlloc。

4、调试代码可以增加 [Conditional(“DEBUG”)] 这样的标签。防止开发版本的代码或者日志发布出去。频繁打Log会对性能有严重影响。

5、对象的Update放到统一的管理器或主线程里面进行更新。

6.、避免使用昂贵的数学函数。比如 pow exp log cos sin tan 等。可使用查找表来作为替代

7、运用对象池,避免重复实例化、分帧运算,避免短时超负荷、数据缓存,避免重复运算及算法

(四) Shader的性能优化经验

1、尽可能减少纹理采样数目,控制绘制顺序、时刻警惕透明物体、减少实时光照和阴影

2、优先使用低精度的数字格式。优先使用half。在现代gpu上fixed等同于half。 部分对精度有特殊需求的情况下才使用float。个别情况下,尤其是与法线相关的时候,使用half容易因为精度不足导致渲染结果错误,这个时候还是应该使用float。

总结

1、CPU

运用对象池,避免重复实例化
分帧运算,避免短时超负荷
数据缓存,避免重复运算
算法

2、 GPU

使用多层次细节LOD
使用光照贴图
静态合批和动态合批
简化着色器
使用平台推荐的压缩格式
减少模型面数
减少贴图大小

3、内存

模型区分高低模
释放AssetBundle
降低模型面数
降低骨骼数量
降低贴图大小

4、 包体

压缩图片
压缩音频
压缩自带库文件
分段下载
字体裁剪

5、 网络

使用压缩性高的通讯协议
数据流量优化

;