优化方式
- 压缩贴图ETC/PVR:贴图是占用资源最大的部分。我对3D贴图基本上都会压缩,2DUI贴图部分压缩。在Android上尽量使用etc格式,IOS上使用pvr格式,非半透有1/8的压缩比。这两种压缩格式类似DX的dds,可以直接被显卡渲染,即降低内存又能减少包大小,提升加载速度(JPG等格式虽然压缩比高但是需要解压成32位色再渲染,增加加了内存和显存还有额外的解压开销)。需要注意以下几点:
- 如果压缩效果不好还可以减成16位色。
- 关Mipmap:UI或者俯视角游戏不需要Mipmap可以关闭减小1/3的体积
- 如果使用ETC,PVR,DDS压缩贴图必须是2的幂(因为区块颜色索引的压缩算法,如果不是2的幂压缩后也会补成2的幂),正方形(PVR还必须是正方形否则会自动补成正方形浪费空间)。处于渲染效率和显存碎片的考虑贴图的大小建议最大1024,最小64,最大不能超过2048。
- 使用九宫,对称贴图:提高贴图复用率
- Shader:利用Shader合并贴图通道,实现灰度图等。Alpha通道存alphatest和高光,贴图一个通道存阴影一个通道存ao等,alpha通道存在贴图的其他通道便于压缩等等。这点在做轩辕传奇的时候大幅使用。
- 压缩动画减少关键帧:前面有介绍
- 及时卸载:在进出场景时,或者打开UI界面等对性能不敏感的时候,卸载资源并调用Resource.UnloadAsset清理引用资源和destroy,System.GC.Collect清理系统资源,前面有介绍。AssetBundle加载时生成、卸载时销毁,这也是比较大的一个坑:)
- 在代码级别上避免不必要的堆内存分配:可以通过静态代码分析检查,另有一篇文章详细介绍。
- 避免频繁New Class:使用内存池。
- Constainer:新版本Unity Constainer已经优化。
- 控制Log输出:我们使用条件限制,Release自动屏蔽一些不重要的日志
- For代替Foreach:新版本Unity已经优化。
- String连接:减少字符串拼接,使用StringBuilder等等。
- delegate:因为内部的链表和装箱拆箱操作,使用频率较高时GC也很高。
- 合理的使用Lambda表达式:例如Unity的粒子系统5.6版本以前GC较高就是这个原因。
- 频繁的临时变量或者list生成,建议定义一个全局的list每次都用该list来计算。
- 需要注意的是类申请在堆上,结构申请在栈上,有时可以使用结构。
- 等等,这方面优化点和文章较多不再累述。
- 内存泄露: Unity是基于引用计数的,一般内存泄漏是资源被Hold住无法释放,内存增长趋势明显、反复切换场景内存膨胀。针对这种情况可以自己写工具输出每个场景的资源日志。也可以使用XCode分析一段时间的内存。
- 表数据。表一般不会卸载,15年帮一个项目做优化,发现光表数据就占用40M。建议使用二进制反序列化使用不要直接使用字符串,并且不在内存中做多份缓存,表数据非常巨大的情况下可以考虑使用完删除。
- 冗余顶点数据:UI贴图Mesh把color,normal等不适用都导出,静态合并会导致内存增大。
- 抗锯齿/Rendertexture:开了抗锯齿会增大内存,高分辨率会增大内存,后期处理可以交换使用Rendertexture不要创建多份。
- GameObject数量:小于1w,节点书过多也会导致加载更新缓慢内存膨胀,可以写工具监控并作为测试时的一项性能指标
耗电
耗电可能不会被大家所重视,但其实在手游上这是一个非常重要的指标。如果游戏打一两个小时就没电了,那出门在外谁敢玩呢?火遍全国的王者荣耀就在省电上做了非常多的优化,我们游戏也是。那么有哪些优化方案呢?
参考:https://zhuanlan.zhihu.com/p/29849244
未完待续...........
-
- 降低CPU/GPU:CPU和GPU非常影响耗电,因为手机CPU和GPU封装一个SOC上的,因此主要体现在手机CPU占用上,当CPU低于25%会非常省电当CPU高于80%耗电就会从呈指数上升。和CPUGPU的优化是重合。
- 内存闪存:内存闪存的使用频率也会影响耗电,和内存闪存的优化重合。
- 网络:和网络的优化重合。
- 限帧:限帧是比较常用的优化手段,手游一般会限帧30帧,早期苹果系统强制限帧30帧后来才开放的。王者荣耀已经把限帧作为一个广告手段了,哪个设备支持都会做一番宣传。但是限帧会降低手感需要权衡。
- 省电模式:当检查到玩家没有插电的时候,配合限帧,降低画质和效果,降低更新频率和LOD等。