UGUI源码分析|04 CanvasUpdateRegistry
管理Canvas重建相关的事情,是一个单例类
在构造方法中,向Canvas的事件里注册了一个方法
protected CanvasUpdateRegistry()
{
Canvas.willRenderCanvases += PerformUpdate;
}
Cavnas会在渲染前,调用这个方法
有两个核心属性:m_LayoutRebuildQueue、m_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();
}