Unity 性能优化体系

ABSTRACT

融合「Unity3D 优化深入浅出」系列五篇(2017-12~2018-01)与 LuaJIT 优化指南,按 CPU / GPU / 内存 / 总线带宽四层瓶颈组织的优化知识框架。底层原理(渲染管线、GC、带宽权衡)至今有效;具体 API 与参数对应 Unity 5 时代,现代项目需映射到 URP/SRP Batcher/Addressables 语境。

总纲:四层瓶颈模型

移动平台统一内存架构下,CPU、总线带宽、GPU、内存任一都可能成为瓶颈。优化第一步永远是定位瓶颈(Profiler / Frame Debugger),而不是盲目动手。优化目标:CPU 的绘制命令恰好被 GPU 消化,互不等待。

CPU 层

  • Update 禁忌:不打日志、不查组件、不声明临时变量、高频复杂运算隔 N 帧。
  • 缓存一切引用:GetComponent 与手动缓存引用耗时差两个数量级。
  • GC 减分配:StringBuilder、for 代 foreach、CompareTag、对象池、慎用 LINQ、场景切换主动 GC。
  • drawcall 预算:按「25K batchs/sec 吃满 1GHz CPU」公式换算目标帧率下的 drawcall 上限。
  • 脚本层(LuaJIT):减少不可预测分支、local 缓存函数、避免 NYI 操作、控制存活临时变量(详见 Lua 游戏脚本开发)。

GPU 层

  • 减顶点:美术优化几何体、LOD、遮挡剔除。
  • 减 overdraw:不透明从前向后绘制、透明从后向前;UI 少用透明设计;粒子慎加透明值。
  • 减实时光照与动态阴影:Lightmap 烘焙、Light Probes、阴影贴图替代。
  • 简化 shader:内置 mobile shader、查表代复杂运算、除改乘、低精度浮点、移动端慎 alpha_test。
  • 减状态切换:少材质、纹理图集、sharedMaterial,利于合批(现代对应 SRP Batcher)。

内存层

  • 双内存模型:Mono 托管堆(GC)+ Unity 原生内存(纹理/网格/GameObject)。
  • 托管侧:对象池、缓存、内置数组、减少调用栈。
  • 资源侧:纹理压缩(PVRTC/ETC → 现代 ASTC)、按需开关 mipmap、及时卸载 AB(注意 Unload(true) 的紫材风险)、控制 GameObject 总数。
  • 读数:Used/Reserved 关系、GfxDriver 即显存占用(现代用 Memory Profiler 包细查)。

总线带宽层

  • AB/纹理过大会拖垮带宽:图集粒度原则——不同时出现的不打包,单张 ≤1024(重度项目 256)。
  • Mipmap 是「内存换带宽」:增 33% 内存,省采样带宽。
  • 物理归入此层管理:Fixed Timestep 取 16~60ms、慎用 Mesh Collider 与真实刚体、最小化碰撞检测次数。

跨平台互通的优化直觉

小程序「快如闪电」类优化文章与 Unity 优化同构:减包体、懒加载、减 setData 频次 ≈ 减 drawcall、减 GC、减带宽——分层瓶颈模型可迁移到任何渲染驱动的应用。

时效性与现代映射

  • Unity 5 时代的 Stats/Profiler、AssetBundle 手动管理、Mono 运行时 → 现代对应:URP + Frame Debugger + Memory Profiler、Addressables、IL2CPP + 增量式 GC。
  • 「避免多线程」已被 Job System/Burst 部分打破;合批逻辑由 SRP Batcher 接管,但「减材质减状态切换」方向不变。

关联概念

来源回溯