元某人也元某人也

Unity GUI 优化

UGUI 性能优化思路与常见瓶颈排查。

本文目录

这篇还没写完:部分小节只有提纲或一句话,补齐前不建议当作参考。

Unity GUI 优化

1.概念

同一 Canvas 下,满足合批规则的多个 UI 元素的网格数据合并到一个顶点缓冲区,仅用一个 DrawCall 提交 GPU 渲染。


2. 合批条件

  • 处在同一 Canvas 下
  • 共享同一个图集(或相同贴图)以及相同的材质实例

注:相同 Shader 的不同材质实例也不会合批。

  • VisibleList 中元素相邻(连续)且 Depth 相同(不被穿插)

3. 合批流程

  1. 按照 Hierarchy 窗口的层级做深度优先搜索,确定基础的渲染顺序(层级越靠上,越优先渲染)。
  2. 计算各元素的 Depth。

Depth 计算说明

  • 不渲染(active = false、alpha = 0、完全在裁剪区域外)→ Depth = -1,且不参与合批
  • 没相交 → Depth = 0
  • 相交(网格重叠)时:
    • 若二者相同材质实例且同一图集(相同贴图) → 两者 Depth 相等
    • 否则,在上方的元素 Depth 需在另一方基础上 +1
  1. 按照 Depth → Mat ID → Texture ID → Renderer Order(Inspector 面板的顺序)从小到大排序,得到 VisibleList。

注:计算 Depth 时已在考虑材质与纹理;此处的比较是在 Depth 相同的情况下进行。

  1. 依次检查 VisibleList 的相邻元素是否满足合批条件。

4. 优化方案

  • 动静分离(动态与静态 UI 使用不同 Canvas)
    • 多个 Canvas 会打断合批,但可减少网格重建所需时间。
    • 动态元素还可能破坏 VisibleList,从而增加 DrawCall。

注:Text 与 Image 分离依然有意义——将两种纹理不同的 UI 元素各自挂到两个 Canvas。Text 与 Image 穿插会导致合批中断。

  • 避免 UI 元素过多与层级过于复杂,影响合批速度。
  • 文本最好用 TextMeshPro 或者图片。
  • 减少 Mask 组件使用(增加 2 个 DrawCall,隔离合批空间)。
  • 使用图集。

5. 重建

概念

CPU 计算网格;UI 元素的 RectTransform 尺寸与锚点变化、视觉元素的改变,都会使得同一 Canvas 下的所有元素发生网格重建。

注:Unity 将网格重建放在子线程上执行,以降低重建消耗;因此 Unity 官方并不强制要求使用多个 Canvas 来规避重建。


要点速查

主题要点
合批本质同 Canvas + 同材质实例 + 同图集/贴图 + VisibleList 相邻且 Depth 相同
Depth重叠且材质/图集不同 → Depth +1,打断合批
多 Canvas打断合批,但利于动静分离、减少重建范围
Text / Image分 Canvas,避免穿插
Mask慎用,+2 DrawCall
重建同 Canvas 内 RectTransform / 视觉变化会触发全 Canvas 重建
仅用于交流学习,记录学习心得