Unity3D官方平台的总结
1、建议使用Unity Profiler工具来分析项目性能。
2、只用Profiler进行分析并不能反映真实的游戏性能,此时建议用Remote Profiler来分析游戏在其它设备上的性能表现(如手游在安卓手机上分析)
3、用编辑器日志观察资源占据空间及构建文件大小。
4、在不同设备上进行测试。
5、使用协程(Coroutines)处理一些不需要逐帧判断的逻辑,采用如下代码进行若干秒或帧的判断:
IEnumerator Callrepeatedly(int waitDuration, Action action) { while(true) { action(); yield return new WaitForSeconds(waitDuration);//或for(int i = 0; i < waitFrameCount; i++){yield return new WaitForEndOfFrame();}若干帧数执行一次动作 } }
6、善用Events、Actions,响应式编程,C#可以用委托创造事件,当事件发生时调用某个函数,然后由该函数去调用订阅了该事件的方法。
7、物理交互方面:
动态刚体数量越少越好。
避免使用网格碰撞体。
Collision Detection Mode设为 “Discrete”。
可以设置Fixed Timestep的值,控制FixedUpdate()调用的时间间隔。
8、尽量使用烘焙光照(Baked Lighting),使用光照探头(Light Probes)来解决烘焙光无法动态变化的问题。
9、使用假阴影减少资源消耗,或者Fast Shadow Receiver插件实现阴影投射。
10、质量设置(Quality Settings)
11、纹理勾选“Generate MipMaps”生成MipMaps来加快纹理载入速度减少渲染时间;限制Max size压缩纹理;使用纹理图集(Atlas)减少DrawCall。
12、UI中使用Sprite时,保证其中的透明区域越少越好,减少OverDraw。
13、减少Canvas的数量,不需要交互的UI就移除掉“Graphic Raycaster”。
14、文本(Text)组件禁用“Rich Text”,图像文本组件无需交互就移除掉“Raycast Target”。
15、UI的材质为空会拖慢运行速度,所以新建一个材质用“UI/Default”着色器,让所有图像文字UI使用该材质。
16、使用Rect Mask 2D来代替Mask组件避免多余的渲染工作,可以搭配Scroll rect使用。
17、避免启用/禁用来不显示菜单元素,可以通过移出场景,或在CanvasGroup上减少Alpha并开启“Blocks Raycasts”。
18、着色器的Keyword越少越好,内容越简单越好。
优化技术的总结
影响性能的因素:
CPU
- 过多的Draw Calls
- 复杂的脚本或者物理模拟
顶点处理
- 过多的顶点
- 过多的逐顶点计算
像素(Fragment)处理
- 过多的fragment,overdraws
- 过多的逐像素计算
带宽
- 尺寸很大且未压缩的纹理
- 分辨率过高的framebuffer
对应的优化方案:
顶点优化
- 优化几何体:减少三角形,尽可能重用顶点,移除不必要的Hard Edge以及纹理衔接,即避免Smoothing splits和UV splits。
- 使用LOD(Level of detail)技术:类似MipMap技术,可以使用Unity的LOD Group组件实现
- 使用遮挡剔除(Occlusion culling)技术
像素优化
- 控制绘制顺序:在Unity中,那些Shader中被设置为“Geometry” 队列的对象总是从前往后绘制的,而其他固定队列(如“Transparent”“Overla”等)的物体,则都是从后往前绘制的。这意味这,我们可以尽量把物体的队列设置为“Geometry” 。
- 警惕透明物体
- 减少实时光照:使用Light Maps或God Rays。
CPU优化
- 减少Draw Calls:批处理(Batching)可以让使用同一个材质的物体的顶点数据打包一起给GPU处理。牺牲内存换取性能的典型例子。Unity进行动态批处理的条件是,物体使用同一个材质并且满足一些特定条件:顶点属性的最大限制为900,使用同一个缩放尺度,使用lightmap的物体不会批处理。多passes的shader会中断批处理。接受实时阴影的物体也不会批处理。动态批处理虽然自动进行但限制太多,所以尽量使用静态批处理。另外纹理图集(Atlas)也是批处理的一种形式。
带宽优化
- 减少纹理大小:Generate MipMaps,Max Size。
- 利用缩放:在Unity中设置屏幕分辨率可以直接调用Screen.SetResolution。
- android的ETC1压缩格式搭配一张alpha图就可以压缩图片。
- 资源创建方式:
1.静态引用,即prefab生成的方式
2.Resources.Load(),资源放在Assets/Resources中
3.AssetBundle.Load,load之后Instantiate(使用最多) - 利用对象池管理对象。
- 利用轮询去Desytoy管理GameObject生命周期。
干货~ 必须赞一下~