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、减带宽——分层瓶颈模型可迁移到任何渲染驱动的应用。

运行时与打包层(evernote 批次补充)

  • JIT 首编译卡顿(Mono 时代):同一函数首次调用远慢于后续,是 JIT 编译开销;全量预热(反射遍历调 GetFunctionPointer)有效但启动 +8 秒不可行;工程化解法是改 Mono 源码在 mono_compile_method 插桩 + 开关圈定热点区间,只对命中的 100+ 类型预热。IL2CPP(全 AOT)后此问题消失,HybridCLR 又以「AOT 泛型补充」形式带回预热议题。
  • Android 出包:StreamingAssets 在 APK 中默认 Store 不压缩;重打包流水线(加密/渠道包)若把 AB 变 Deflate 会显著拖慢加载——AB 加后缀名 + aaptOptions.noCompress 是标准解法。
  • 帧率与温控:关 VSync 用 targetFrameRate 限帧、随之调大 Fixed Timestep 减物理次数、待机 FPS 降到 1——省电控温三件套;少用 Update 系函数,改事件驱动。
  • 视野外粒子仍 Update:用 OnBecameVisible/Invisible 配合缩小的 MeshRenderer 容器整组启停。
  • UI 减资源直觉:对称贴图只存一半、绘制时镜像(NGUI 镜像填充扩展),少量顶点换大量内存;九宫/平铺复用同理。
  • 美术规范方法论:口头/文档规范无效,必须做成 Editor 菜单强制校验;基准机型按 gfxbench 档位预留性能空间;纹理一律压缩格式真机验证,杜绝 RGBA32 滥用;性能测试禁用「同资源复制 N 份」(数据失真)。

时效性与现代映射

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

关联概念

来源回溯