Unity优化摘要
整理以前的乱七八糟的笔记。。。提取要点。
目录
物理
- 按需求为GameObject设置Layer,减少不必要的碰撞检测
射线
- 只在需要时才发射射线
- 控制射线的数量、长度和遮罩
- 避免检测复杂碰撞体
- 如果要检测MeshCollider,尽量使用
convex
- 如果要检测MeshCollider,尽量使用
刚体
- 避免移动不带刚体的碰撞体(静态碰撞体)
- 多级对象只在最外层的父对象上添加刚体即可,不用给每个子物体添加刚体
脚本
- 减少代码执行次数,只运行需要的代码
- 使用缓存,减少查找和内存分配
- 避免调用高开销的Unity API
- Find()
- position & rotation
- 向量运算
- SendMessage() & BroadcastMessage()
- 当对象不可见时停止执行不必要代码
- 避免装箱拆箱
- 每次调用返回数组的Unity方法或属性,都会创建新的数组,应该使用缓存
- 协程、方法引用会引发堆内存分配
- 避免使用LINQ和正则表达式,它们会引发装箱操作
- 在不注重性能的时刻(例如加载画面)回收内存和尽量多的分配所需的内存
渲染
渲染流程
- CPU检测哪些对象需要渲染及其渲染方式
- CPU将需要渲染的对象的渲染数据编排到DrawCall指令中
- CPU将某些共享配置的对象的数据合并到同一个DrawCall中(批处理)
- CPU为每次DrawCall创建一个称为Batch的数据包
- CPU向GPU发送DrawCall和SetPassCall指令
- GPU根据DrawCall和SetPassCall指令绘制画面
降低CPU压力
- 减少需要渲染的对象的数量 - 可以减少Batch和SetPassCall
- 减少可见对象数量
- 缩短相机绘制距离
- 在代码中设置Camera.layerCullDistances来控制相机在不同Layer的剔除距离
- 适当使用Occlusion Culling,这会产生额外的CPU开销
- 减少每个对象需要渲染的次数 - 可以减少SetPassCall
- 烘焙光照贴图预先计算静态对象的光照信息,减少实时计算量
- 少用反射探针,它们会时Batch数量大增
- 在Quality Settings中调整阴影属性,控制阴影质量
- 运行在高性能设备上的具有较多实时光照、阴影和反射的游戏适合使用Deferred Rendering
- 运行在低性能设备上的没有实时光照、阴影和反射的游戏适合使用Forward Rendering
- 将对象合并到更少的批处理中 - 可以减少Batch和SetPassCall
- 静态批处理 - 用于处理临近的Batching Static对象,会占用更多的内存
- 动态批处理 - 用于处理非静态对象,它的限制比较多,而且会占用更多的CPU时间
- UI批处理 - 减少UI重叠,动静分离等
- GPU实例 - 用于处理集中出现的大量同种单个对象
- 纹理图集 - 将多个纹理贴图合并到一张大的纹理贴图中
- 手动合并Mesh - 将共用相同材质和纹理的Mesh合并,会影响对象的剔除
- 优化蒙皮
- 减少SkinnedMeshRenderer的数量
- 减少SkinnedMeshRenderer对象的顶点数
- 使用GPU Skinning
降低GPU压力
- 优化填充率
- 避免堆叠透明材质、粒子和UI元素,减少重绘
- 减少图像特效
- 优化片元着色器
- 优化显存带宽
- 纹理压缩
- Mipmap
- 优化顶点处理
- 降低Mesh复杂度
- 使用LOD
- 使用法线贴图
- 禁用不使用法线贴图的模型的顶点切线
- 优化顶点着色器
UI优化
- 简化UI结构,减少组合、重叠UI
- 拆分画布,将不常变化的UI和经常发生变化的UI分离
- 通过禁用/启用Canvas组件实现频繁显示和隐藏的画布,但禁用Canvas组件时并不会停止UI的MonoBehaviour
- 不要使用alpha=0这种方式来隐藏UI,这样做仍然会发送UI渲染数据
- 不要把对象当作文件夹使用
- 禁用不可见相机的输出(打开全屏UI时相机仍然会渲染场景中的物体)
- 取消勾选不接收射线的UI的RaycastTarget属性
- 文字会被渲染成面片,它含有不可见的边框,小心由此产生的UI重叠
- 不要使用Best Fit
- 使用TextMeshPro代替内置的Text
DrawCall优化
- 减少纹理数量,尽量使用纹理集
- 把所有不会移动的网格都标记为Static
- 尽可能烘焙最大尺寸的光照贴图
- 不要为零碎的小物体烘焙光照贴图,应该使用Light Probe照亮它们
- 访问Renderer.material会创建材质实例并破坏批处理,尽量使用Renderer.sharedMaterial代替
- GPU Instancing
- 在桌面设备上表现良好但在移动设备上运行缓慢
- 网格数量在50-100之间时效果好,具体取决于设备
几何体优化
- 尽量降低网格复杂度
- 删除不可见的面
纹理压缩
- 在移动设备上优先使用ASTC压缩
- 若ASTC不可用,则使用ETC2(Android)/PVRTC(iOS)
- PVRTC和ETC压缩需要正方形纹理
相机
Clear Flags
- 避免在移动设备上使用 Don’t Clear
- 避免在移动设备上使用Untiy默认的天空盒(计算开销大),禁用方式:
- 设置相机的 Clear Flags 为 SolidColor
- 在Lighting窗口中移除 Skybox Material
- 在Lighting窗口中设置 Environment Lighting - Source 为 Color
Occlusion Culling(遮挡剔除)
- 剔除相机视锥体内因被遮挡而不可见的物体
- 能够提升性能
- 增加磁盘空间占用(存储构建是烘焙的剔除数据)
- 增加内存占用(加载剔除数据)
- 在代码中设置Camera.layerCullDistances来控制相机在不同Layer的剔除距离
还没整理完