目标
使用Unity提供的工具收集以及分析数据来对项目进行优化,找出性能问题是由什么导致的,然后解决问题,恢复以及优化性能
重点在以下四个方面:
- 渲染优化
- 脚本优化
- 资源优化
- 平台优化
接下来就从这四个方面简单介绍如何优化
优化
为什么要优化?因为优化能够创造令玩家满意的流畅的游戏体验
在优化之前我们首先要明确游戏运行的平台,不同的平台运用了不同的技术。通常来说,PC平台的技术限制更小,而移动平台拥有严格的技术限制,在设计时需要围绕这些技术限制进行设计,并且在开发前规定一个最低的规格,以最低规格进行定位和优化。
而优化的最主要的目的就是:
- 保持帧率
- 避免某些环境的掉帧
- 避免崩溃
如果并没有出现以上问题,那就不需要优化,优化的过程就是解决上述问题的过程。
- 对于帧率而言,可以使用Unity在Game窗口下的Stat窗口监视帧率,快速获取帧率信息
- 对于某些严重BUG就只能重现崩溃来找出BUG的位置
渲染优化
1.
渲染优化的问题主要是GPU瓶颈的问题,如果需要花费过长的时间渲染一个帧,就会导致帧的渲染延迟。
一般GPU瓶颈有三种可能:
- 像素填充:在Unity的Player Settings中设置降低分辨率,如果性能有明显提升,那很有可能是像素填充的问题。通常过度的片元着色器的使用,以及相同物体的多次渲染都会导致这个问题。
- 内存带宽:在Unity的Quality Settings中减少当前平台和目标对象的贴图质量,如果性能有明显的提升,那很有可能是内存带宽的问题。
- 顶点处理:如果不是上述原因,那很有可能就是顶点处理的问题。
解决方法:
- 我们应该使用为移动平台定制的shader,避免复杂的片元着色器,减少透明材质以及特别耗的特效的使用。
- 通常只有通过减少贴图的内存占用来提高游戏的性能——减小纹理大小或使用多级贴图。
- 同样使用移动平台的shader,避免复杂的顶点着色器,使用LOD,减少模型的顶点数量。
2.
还有一种问题就是过度使用SetPass Call和Draw Call,过度的设置渲染状态也会导致GPU瓶颈。使用Static Batching、Dynamic Batching以及GPU Instancing可以对其进行优化,这些技术都可以让游戏对象一次绘制多个网格或对象,减少Draw Call的调用,节省开销。
在Unity的Frame Debugger中,可以看到所有的Draw Call,通过分析Draw Call来找出需要优化的内容。
3.
渲染路径的选择也会影响最后的渲染性能,通常我们会使用Forward Rendering和Deferred Shading,他们各有优缺点,但如果过度使用也会导致渲染问题,需要对其进行平衡
脚本优化
这主要涉及到了Unity的垃圾回收(GC)的机制,Unity会对那些不处于使用状态的数据进行处理,如果同一时间有大量垃圾需要处理,就会导致帧率的突然下降,使用Profiler就会发现尖峰的存在。
通常的解决方法是:
- 周期性的主动进行垃圾回收
- 使用对象池来减少对象的实例化和销毁
- 避免在频繁调用的函数中分配内存,这一点主要在字符串、函数调用上比较明显
在游戏中过度的使用物理和碰撞也会严重降低性能,进行分层碰撞、选择简单的碰撞体和减少rigidbody的使用都可以提升效率。
同样过度使用NavMesh进行导航也降低性能,需要平衡它们之间的关系。
资源优化
主要就是两点:纹理压缩和模型压缩
- 纹理压缩:针对平台和需要的纹理质量选择相应的压缩格式,对于没有深度变化的贴图禁用Mipmaps
- 模型压缩:主要就是减少游戏对象复杂 的层级以及优化模型本身的结构和大小(这方面我涉及较少)
平台优化
对于PC平台而言,限制并没有那么多。通常的平台优化都对于移动平台,就如之前所说的,在开发前规定一个最低的规格,以最低规格进行定位和优化,那么我们在分析过程中,在PC分析之后应在目标平台上测试,因为PC上的分析会和目标平台的分析产生偏差。
对于移动平台的调试问题,我也测试的较少,简单来说就是:
- 在Unity中配置环境
- Build Settings切换平台
- 启用Development Build进行测试
- 启用Autoconnect Profiler允许Profiler连接到游戏
- 启用USB调试
- 通过Adb连接手机
其他优化
一个是粒子,高密度的粒子使用会导致性能的下降,同样可以使用对象池或裁剪技术;并且粒子中的不同模块也会导致性能的下降(比如光照最耗性能)
还有一个是后处理效果,虽然后处理效果能给游戏带来更好的视觉体验,但是通常会占用大量资源。如果必须要使用它们,就一定要使用优化过的效果(可以尝试Unity Post Processing Stack V2)