一.天空盒没有必要的话不要显示
如图,一个空场景的定点和三角面都大几千,如果是2d游戏或者用不到天空盒,在MainCamera把ClearFlags换成其他合适的模式
去掉天空盒的无谓开销后属性如下
二.动静分离
这个我了解的方法一般是用新增canvas做
方法一 在当前canvas平级路径新增一个canvas , 有需要动态会导致ui重建的元素就放到新增canvas中,动完再放回来。
这个缺点是显示层级处理起来可能比较麻烦,我没用过。
方法二 这个是我项目中采用的方法,在会导致ui重建的元素上添加canvas组件。优点是方便,缺点是你可能有很多地方需要用,但是创建大量canvas的话,据说性能开销反而不太好,之前看到有帖子上说全局尽量不要超过3-4个canvas,不求甚解未验证。
添加canvas组件的物体,如果需要触发事件,需要添加GraphicRaycaster组件才能正确监听事件
三.批处理 FrameDebugger
unity内置的工具,可以显示当前场景合批的元素和打断合批的元素,很方便找到drawcall激增的元凶
四 随笔杂项
Mask会增加一个Draw,并且Mask里面的图片不会和外面的图片合批
空Image会打断合批
RichText会造成三角面增加
颜色渐变和可以用material控制,本质是更改Tint属性,这样既能满足颜色渐变,又能避免网格频繁重建造
UI排列的时候尽量让来自不同图集的UI元素不重叠
拼接字符串不要用+,用string.Format代替。 string.Format内部是使用stringBuilder实现的
性能优化一般要在项目前期和开发期就做好,尽量避免后期为优化而优化。
比如美术方面要顶好标准,模型的骨骼数(<25-30),三角面数,纹理尺寸,贴图大小,字体包大小等
(非必要的双面材质,有的模型只能看到正面,反面就简易些,片面越少越好)
程序方面
常用的模块化的有
使用图集,控制图集大小,尽量降低drawcall。
使用对象池,将频繁或大量使用的物体移出屏幕或隐藏,避免大量销毁重建。
使用分帧处理,避免CPU峰值造成的卡顿,比如在刚进入场景时的大量创建instantiate,可以使用协程,每一帧生成一部分
scrollview的循环重用等
IL2CPP打包代替Mono,能提供高运行效率。IL2CPP 打包的话,Android或IOS的代码一定要用宏括起来,不然会出错
LOD多层次细节
避免使用实时阴影,可以用shader代替,如若使用要合理控制下分辨率和阴影距离。
自带的文字阴影或描边性能很差,可以通过美术或shader或TextMeshPro解决
overdraw 同一时刻只会有一个全屏显示,九宫格镂空
小的方面比如去掉不需要点击的UI的RaycastTarget,不要使用GameObject.find这类高消耗的方法,特别是注意不能放到Update里。
尽量少使用会调用GC的方法。比如字符串拼接,用stringBuilder代替String,或用string.format亦或是$符号操作。再比如yiled return 如果带返回值的 yiled return 0 等,可以用yield return null
尽量不使用MeshCollider,或者尽量减少MeshCollider的面数
如果使用AssetBundle,注意回收
2d游戏,不需要的去掉天空盒,可以减少大量三角面
ios图片格式 PVRTC4 如果模糊就用 RGBA Compressed ASTC 6x6 block
androids图片格式 ETC DXT
省电
支持自动省电模式:如当玩家1min没有操作时自动进入省电模式.
降低FPS.
将分辨率缩放到最低(如1280 * 720)
动态降低分辨率参考 降低Update / LateUpdate 等高频函数的执行频率.
关闭一些显示效果,如后处理皮肤、bloom、抗锯齿等.
如果开了实时阴影,考虑降低更新频率、调低效果参数等.