管理Canvas重建相关的事情,是一个单例类

在构造方法中,向Canvas的事件里注册了一个方法

protected CanvasUpdateRegistry()
{
    Canvas.willRenderCanvases += PerformUpdate;
}

Cavnas会在渲染前,调用这个方法

有两个核心属性:m_LayoutRebuildQueuem_GraphicRebuildQueue

两个队列,前者用于管理需要重构的布局,后者用于管理需要重构的图形

UGUI组件一般会根据需要,在OnEnalbe或者其他时候向CanvasUpdateRegistry注册这两个属性

而方法PerformUpdate则是对着两个队列内的属性进行重构,大概顺序如下:

剔除失效的组件

CleanInvalidItems();

对布局组件排序,按照父节点数量排序

m_LayoutRebuildQueue.Sort(s_SortLayoutFunction);

然后开始遍历更新,这里的CanvasUpdate.PostLayout是一个枚举,象征重建的不同阶段而已,会传入Rebuild方法里,具体含义由方法去实现

for (int i = 0; i <= (int)CanvasUpdate.PostLayout; i++)
{
	for (int j = 0; j < m_LayoutRebuildQueue.Count; j++)
    {
        var rebuild = m_LayoutRebuildQueue[j];
        try
        {
            if (ObjectValidForUpdate(rebuild))
                rebuild.Rebuild((CanvasUpdate)i);
        }
        catch (Exception e)
        {
            Debug.LogException(e, rebuild.transform);
        }
    }
}

最后就是调用更新完成的方法

for (int i = 0; i < m_LayoutRebuildQueue.Count; ++i)
    m_LayoutRebuildQueue[i].LayoutComplete();

图形重构的顺序类似,只是最开始会调用一次图形裁剪

ClipperRegistry.instance.Cull();

ICanvasElement

大部分UGUI组件都需要实现这个接口,只有实现这个接口才可以被重构

public interface ICanvasElement
{
    void Rebuild(CanvasUpdate executing);
    Transform transform { get; }
    void LayoutComplete();
    void GraphicUpdateComplete();
    bool IsDestroyed();
}