【总结】Unity游戏优化

1、Profiler中一项"WaitForTargetFPS"费资源过高的原因

画面撕裂,显卡渲染输出的速度与显示器不同步, 如果显示器刷新的同时,显卡创造了新的帧,就会出现上半显示器显示前一帧,下半显示器刷新到下一帧画面的“撕裂”现象。常见于高帧数显卡与低帧数显示器上~

垂直同步(V-Sync),通过延时让显卡等显示器输出完毕后再“生产”下一帧画面,将游戏帧数锁定到和你的显示器刷新频率一样,从而达到画面的同步。

WaitForTargetFPS,是用于防止撕裂的。WaitForTargetFPS消耗越高,说明被压缩的帧数越多,Setting里关掉垂直同步就可以了

FreeSync技术则是让显示器的刷新率不再固定为60Hz,成为一个动态变量,当显卡完整渲染完一张画面后,显示器就可以输出了。 最大化发挥显卡性能,不会因垂直同步而掉帧

2、代码细节优化

  • 协程比Update节能,尽量不要在update函数中做复杂计算,有需要可以隔N帧计算一次
  • 不用的事件函数如Update应该删除
  • 简化计算,如用乘法代替除法,少用复杂的数学函数,用合适的精度
  • 减少使用临时变量,尽量优化循环的时间空间复杂度
  • 减少动态的生成字符串,用StringBuilder
  • 减少使用Find,GetComponent等耗时API,可以在start中预先存起来
  • 减少函数调用栈,用x = (x > 0 ? x : -x);代替x = Mathf.Abs(x)
  • 尽量不要在方法中动态new array,推荐用类变量或者传入参数
  • OnGUI少用,最好只在一个脚本中使用。用UGUI

3、用Profiler优化

  • ProcessRemoteInput 是引擎在Editor下调用的东西……
  • Log中可以找到所有打包的资源(AssetHunter)

4、场景优化

  • 无用的组件比如Animation最好移除
  • 少用耗性能的碰撞体,比如mesh,wheel,sphere...尤其是移动端
  • 不要在场景预先放好太多东西,而是用动态生成,逐渐加载
  • 阴影=阴暗+影子,建议使用实时影子时把阴暗效果烘焙出来,不要使用灯光来调节光线阴暗。
  • 在效果相似时选择最节能的。比如硬阴影,低分辨率贴图,static光照烘焙,少用法线贴图,优化粒子特效或用UV动画
  • 大场景中使用线性雾,使远距离对象或阴影不易察觉,因此可通过减小相机和阴影距离来提高性能
  • 使用遮挡剔除,LOD
  • 用skybox做远景

5、资源加载优化

  • 使用对象池
  • 合并使用同贴图的材质球,合并使用相同材质球的Mesh
  • 动画文件我们是单独分离出来的,以供多角色共用
  • 减少模型面数和总数。但是场景不用合并成一个mesh,这样会使得同屏的面数增加
  • 将透明通道的对象置于TransparentFX图层。Tag,Hieratchy,Layer养成良好的条理化习惯
  • Mesh的压缩仅仅是减少打包文件的大小,并不会减少运行时的内存消耗。而减少动画关键帧,则会让两者都有所减少,一般情况下我们都应该开启。
  • 减少手机上使用的 .NET 库的大小,通常用 .NET 2.0 Subset ,另外Unity会自动随着API的使用提高安卓版本

Textures资源设置

  1. 对于Texture等资源来说, Unity会把资源再编码成它自己的内部格式,所以源文件格式并不重要。而内部格式文件占空间越小,存储空间优化就越好
  2. 可以用压缩来优化存储空间,但会损失一些时间,而且内存消耗不变

6、Shader优化

  1. 少使用的函数:pow,sin,cos等
  2. 用合适大小的数据类型
  3. 对于不支持的设备不使用逐像素、实时阴影、屏幕特效等画面效果。Shader要做到平台适用且高效

7、内存管理,GC回收

  1. Mono堆内存回收用System.GC.Collect(); 可避免系统在不合适的时间进行自动GC
  2. Unity内存回收用Resources.UnloadUnusedAssets(); 其内部本身也会调用 GC.Collect()
  3. AssetBundle.Unload释放AssetBundle文件内存镜像
  4. Reources.UnloadAsset(Object)释放硬盘加载的所有Asset资源,慎用

相关推荐