目录
Unity 之 一些资源标准、性能优化点整合整理
零、总起
一、模型
二、图片
三、音频资源
四、灯光
五、碰撞体
六、font
七、UGUI
八、移动端性能优化心得
优化思路:
1)和美术指定好相关资源的规范
2)代码框架,合理的管理资源、多线程使用、对象池的使用、算法的优化、一些API 尽量不要在 Update 中频繁使用、UGUI开发规则 等在代码开发中的规范
3)最后,一起应用开发完之后,在使用 profiler 、frame debugger 在最性能分析,针对之前未能顾忌到的点在做优化
性能分析工具:
1)Unity : Profiler、FrameDebugger、PhysicalDebugger
2) Android Studio 、IOS XCode
3)第三方:UWA 等
关键:建模原点人物脚底,其他根据情况物体中心,移动端建议面数 1500 面以下,同屏控制50000 以下,剔除断点和孤立点,根据场景,可以使用 遮挡剔除、LOD 技术;
1、所有角色模型最好站立在原点。没有特定要求下,必须以物体对象中心为轴心。
2、面数的控制。移动设备每个网格模型控制在300-1500个多边形将会达到比较好的效果。但是、如果游戏中任意时刻内屏幕上出现了大量的角色,那么就应该降低每个角色的面数。
一般情况:正常单个物体控制在1000个面以下,整个屏幕应控制在7500个面以下。所有物体不超过20000个三角面。
3、整理模型文件,仔细检查模型文件,尽量做到最大优化,看不到的地方不需要的面要删除,合并断开的顶点,移除孤立的顶点,注意模型的命名规范。模型给绑定之前必须做一次重置变换。
4、可以复制的物体尽量复制。如果一个1000面的物体,烘焙好之后复制出去100个,那么他所消耗的资源基本和一个物体消耗的资源一样多。
5、根据情况,可以使用 遮挡剔除、LOD 技术
6、大场景尽量建成一个模型,一个材质,方便合批处理
7、多个单开模型,公用材质,可以 mesh 合并,方便合批,减少 drawcall
关键:移动端尺寸 1024 及以下,关闭不必要的读写功能,UI中关闭 mipmap,模型中可根据情况开启 mipmap,使用图片压缩工具在合适压缩原图,合理使用图集进行合批处理,没有alpha 通道就用 jpg,需要alpha 才用 png
1、贴图文件尺寸须为2的N次方 (8、16、32、64、128、256、512、1024)最大贴图尺寸不能超过1024x1024,特殊情况下尺寸可在这些范围内做调整。
2、关闭不必要的 Read/Write Enabled;
默认情况下,纹理被加载到内存,提交给 GPU 时复制一份到显存中,内存中这一份会被删除掉。如果你勾选了 Read/Write Eanbled 选项,那么对应纹理的内存将不会被删除,你可以通过 Texture.GetPixels
和 Texture.SetPixels
等 API 进行读写,导致的问题是额外多一倍的内存。
3、根据情况关闭不必要的 Generate Mip Maps;
4、合理使用图集 ,sprite packer,texture packer (TexturePacker - Create Sprite Sheets for your game!)
5、没有alpha 通道就用 jpg,需要alpha 才用 png
1、短音频 使用 wav,长背景乐使用 压缩的MP3;
如果使用任何压缩格式(如 MP3 或 Vorbis),Unity 会将其解压并在构建时重新压缩。这样会导致两个有损通道,从而降低最终质量。
2、load type ,小剪辑 (< 200 kb 短音频) 应采用 Decompress on Load。将声音解压缩为原始 16 位PCM 音频数据,会导致 CPU 开销和内存占用,因此,这仅适用于短声音。
中等剪辑 (>= 200 kb 长音频) 应保持为 Compressed in Memory。
3、实现静音按钮时,不要只是将音量设置为 0。可以销毁 AudioSource 组件,从而将其从内存中卸载,这样,播放器不需要过于频繁地切换开关。
4、合理 控制 AudioSource 组件,可以使用对象池技术,合理控制数量
1、控制实时光的数量
2、使用 光照贴图 lightmap
3、阴影也占用较大性能,取消不必要的阴影接收和投射
1、简化碰撞体;尽量少用 Mesh Collider 作为碰撞体
2、在 FixedUpdate 中移动物理体
3、Project Settings 中的默认 Fixed Timestep 是 0.02 (50 Hz)。根据目标帧率对此进行更改(例如,对 30 fps 设置为 0.03)。
否则,如果帧率在运行时下降,也就是说 Unity 每帧都多次调用 FixedUpdate,可能会因物理内容过多而造成 CPU 性能问题。
4、使用 physical debugger 实现可视化
1、字体库的必要裁剪、留下常用的字体,去除不必要的字体
1、动静分离。canvas 和 子 canvas ,注意父子canvas 不会一起合批处理
如果是包含成千上万个元素的大型画布,更新单个 UI 元素就必须更新整个画布,这可能会造成 CPU 尖峰。
利用 UGUI 的功能可以支持多个画布。根据 UI 元素的更新频率要求,划分这些元素。将静态 UI 元素保留在单独的画布上,将同时更新的动态元素保留在较小的子画布上。
确保每个画布中的 UI 元素都有相同的 Z 值、材质和纹理。
2、限制GraphicRaycaster 和禁用Raycast Target
输入事件(如屏上触摸或单击)需要 GraphicRaycaster 组件。它只是循环处理屏幕上的每个输入点,检查它是否在 UI 的 RectTransform 之内。
从层级视图的顶层画布中移除默认的 GraphicRaycaster。只向需要交互的各元素(按钮、滚动矩形等)添加 GraphicRaycaster。
另外,在所有不需要 Raycast Target 的 UI 文本和图像上将其禁用。如果是包含很多元素的复杂 UI,所有这些小更改都可以减少不必要的计算。
3、避免使用布局组 layout
布局组的更新很低效,应少量使用。如果内容是动态的,应完全避免不用,而是使用锚点进行比例布局。或者,创建自定义代码,在Layout Group 组件设置 UI 之后,将该组件禁用。
如果动态元素确实需要使用布局组(水平、垂直、网格),应避免嵌套它们,从而改善性能。
4、大型列表和网格视图开销很大。例如 scrollview 可以重复使用其中的item
如果需要创建大型列表或网格视图(如包含成百上千项目的物品栏屏幕),可以考虑重复使用较小的 UI 元素池,而不是为每个项目都创建 UI 元素。
5、避免大量使用重叠元素
对大量 UI 元素(如卡牌游戏中堆叠的卡牌)分层会造成过度绘制。自定义代码在运行时将分层元素合并到更少的元素和批次中。
6、使用全屏UI 时,隐藏其他全部内容,看不懂场景的时候,必要的使用禁用 3D 场景渲染
如果暂停屏幕或者启动屏幕遮住场景中的其他全部内容,则禁用摄像机对 3D 场景的渲染。同样,禁用隐藏在顶层画布之后的所有背景画布元素。
由于不需要以 60 fps 的帧率进行更新,可以考虑在全屏 UI 过程中降低 Application.targetFrameRate。
将摄像机分配给世界空间画布和摄像机空间画布
将 Event 或 Render Camera 字段留空会使 Unity 填充 Camera.main,这会导致不必要的开销。
尽可能使画布 RenderMode 采用 Screen Space - Overlay,这样就不需要摄像机。
CPU端性能优化
GPU端性能优
内存优化
参考文献:
1、移动游戏优化指南 | Unity 中文课堂