Graphic.Rebuild() 方法,是 Unity UI 系统核心的渲染更新机制。
Graphic.Rebuild() 方法详解
cs
/// <summary>
/// Rebuilds the graphic geometry and its material on the PreRender cycle.
/// </summary>
public virtual void Rebuild(CanvasUpdate update)
{
if (canvasRenderer == null || canvasRenderer.cull)
return;
switch (update)
{
case CanvasUpdate.PreRender:
if (m_VertsDirty) // 顶点数据脏标记
{
UpdateGeometry(); // 更新几何体(关键步骤!)
m_VertsDirty = false;
}
if (m_MaterialDirty) // 材质脏标记
{
UpdateMaterial(); // 更新材质
m_MaterialDirty = false;
}
break;
}
}
完整的 UI 更新流程
Graphic 组件内部的各种脏标记检查逻辑 核心流程如下:
1. 脏标记系统(Dirty Flags)
cs
public class Graphic : UIBehaviour
{
// 各种脏标记
protected bool m_VertsDirty; // 顶点数据需要更新
protected bool m_MaterialDirty; // 材质需要更新
protected bool m_ShouldRecalculateStencil; // 模板测试需要重新计算
protected bool m_ShouldRecalculateClipping; // 裁剪需要重新计算
// ... 还有其他标记
}
2. 触发脏标记的方法
cs
// 这些方法会设置相应的脏标记
public virtual void SetVerticesDirty()
{
if (!IsActive()) return;
m_VertsDirty = true;
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
}
public virtual void SetMaterialDirty()
{
if (!IsActive()) return;
m_MaterialDirty = true;
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
}
public virtual void SetAllDirty()
{
SetLayoutDirty();
SetVerticesDirty();
SetMaterialDirty();
}
3. 完整的更新流程图
当以下情况发生时: 1. 颜色/透明度变化 2. 材质变化 3. 纹理变化 4. RectTransform 变化 5. 启用/禁用组件 ↓ 调用 SetVerticesDirty() / SetMaterialDirty() ↓ 注册到 CanvasUpdateRegistry ↓ 等待 Canvas 的渲染循环 ↓ CanvasUpdate.PreRender 阶段 ↓ 调用 Graphic.Rebuild(CanvasUpdate.PreRender) ↓ if (m_VertsDirty) UpdateGeometry() → OnPopulateMesh() ↓ if (m_MaterialDirty) UpdateMaterial() ↓ 清除脏标记,完成更新