在面试上有被问到这个两个问题,结合自己经历过的项目和看过的优化方案。做一次总结。
内存里有什么
Unity3D游戏引擎是如何分配内存的。有三大部分
Unity3D内部的内存
Mono的托管内存(值类型和引用类型)
第三方引入的DLL
Unity3D内部的内存
资源:纹理,网格,音频等等
GameObject和各种组件
引擎内部逻辑需要的内存:渲染器,物理系统,粒子系统
当然还有这样的分类
资源内存
代码内存(Mono内存,引擎使用内存)
第三方库(sdk,插件)
优化角度
场景:将场景中的材质相同满足一定条件的模型合并,减少静态物体的DrawCall;看不到模型背面,减少面数。使用lightingMap代替实时灯光。结合自己参与的项目,在场景中有使用特效的门,就改成代码只加载下一个要被看到的门。
角色怪物: 根据关卡按需加载,这个还带来切换场景的Loading等待时间缩短。项目中,场景bundle加载完毕,再加载怪物。主角模型3500到4000,骨骼不超过40根,三个material。
动作资源:删除关键帧,压缩精度
特效:监控proticlesystem和动画数量。为了特效分级控制,挂接一个组件,开中档特效的时候,修改组件的属性,让部分失效。
UI图集:按需区分图集,平衡共有图集数和使用率。拆分Alpha,规范的正方形或图形进行尺寸压缩。自己项目一个UI界面控制在3个图集,一个进入就加载图标的图集,一个是公用的UI(按钮等),第三个是这个UI界面独有的图集。
资源及时卸载
避免内存泄漏:被依赖的ab过早卸载,会导致资源重复加载。
表格:二进制,相对csv,解析快,没有gc,字典存表。
帧频:drawcall 人物做预处理,各个部分的mesh都提取出来。mesh做预处理,在游戏中合并在低端机,一次混合比八次Drawcall更有性能上的优势。(龙之谷手游优化)锁帧30帧,降低电耗。
UI:动静分离,减少UIMesh动态更新,控制飘字的最大数量。还有减少rendertexture的数量。直接把3D模型在UI界面上使用,这需要在UI界面在设计的时候支持。
减少更新。这是Unity官方推荐的animator optimize game object,还有及时停止不必要的update,减少Billboard和Animation的updade操作。比如位移旋转,都会消耗比较大,特别在低端机上,适当减少update操作,会带来帧率优化。
渲染效率的控制。针对移动平台的shader。减少采样通道。
使用assetBundle.资源分离和共享。实现资源在先更新。
代码裁剪使用stripLvel使用.net2.0subset。
裁剪粒子系统。粒子的发射数量控制在50个。
音效:可以使用单声道就使用单声道,根据效果压缩大小。
Texture: Android平台ECT。iOS平台使用PVRTC.UI纹理上从设计层面减少纹理的色差范围。可以用使用九宫格的使用九宫格。UI上关闭mipmap。Read&write不开启。开始除了在GPU上有一份,CPU中也有一份。
参考
内存 vs 帧率 - 龙之谷手游优化实战(Unite2017分享实录)
Unity内存优化之美术资源篇