学习博客:
https://blog.csdn.net/qq_28820675/article/details/106245195

CanvasUpdateSystem中更新布局的具体实现系统。

布局 LayoutSystem

也就是上一篇中说的 Canvas刷新系统 中,重建得2个数组之一Layout数组是怎么来的、又是怎么重建得。

什么时候标记

也是用脏标记。时机一般为尺寸改变时(RectTransform Dimensions)。

标记后干什么

UGUI组件(如Graphic、ScrollRect…)在需要布局处理时(也就是被标记或OnDisable时),会把自身的RectTransform组件用LayoutRebuilder对象包装,之后加入Layout数组

重建布局

这个的执行时机,在画布刷新系统那篇里有细写。

1
2
3
4
5
6
7
8
9
10
11
12
13
// CanvasUpdateSystem触发重建
public void Rebuild(CanvasUpdate executing)
{
switch (executing)
{
case CanvasUpdate.Layout:
PerformLayoutCalculation(m_ToRebuild, e => (e as ILayoutElement).CalculateLayoutInputHorizontal());
PerformLayoutControl(m_ToRebuild, e => (e as ILayoutController).SetLayoutHorizontal());
PerformLayoutCalculation(m_ToRebuild, e => (e as ILayoutElement).CalculateLayoutInputVertical());
PerformLayoutControl(m_ToRebuild, e => (e as ILayoutController).SetLayoutVertical());
break;
}
}

布局组件 LayoutGroup

经过对LayoutSystem、LayoutRebuilder的分析,布局接口的触发规则已经被摸清楚了。

虽然UGUI组件中有一些组件都继承了ILayoutElement接口(例如:Image,Text,ScrollRect,InputField),但它们并不会涉及对接口方法的实现。这是因为这些组件主要是布局操作的接收方,只需要通过该接口被布局实施方所发现即可。而UGUI中负责这些接收物体的布局设置功能主要是由LayoutGroup衍生的子类组件来完成。

LayoutGroup,是布局组件的基类(GridLayoutGroup、HorizontalOrVerticalLayoutGroup)。先对纵横布局组件(HorizontalLayoutGroup、VerticalLayoutGroup)进行分析。

组件介绍

Padding:内部边距,调整实际用于布局区域的大小
Spacing :子物体直接的间隔
Child Alignment :子物体对齐方式
Child Controls Size :组件控制子物体尺寸开关,开启时组件可以更改物体尺寸。
Child Force Expand :组件控制子物体填充区域开关,若可以修改尺寸则会改变子物体尺寸填充区域,若不可以修改尺寸,则根据区域大小均衡分布子物体。

布局过程

以HorizontalLayoutGroup为例。

1.对该GameObject下所有子物体(只做一次GetChild)进行遍历,获取其子节点下所有没有被标记ignoreLayout的物体。放到一个List中。

2.对List中的每一个Cell都进行尺寸与位置的计算。然后设置其属性。

ContentSizeFitter

布局系统中尺寸调节组件。

ContentSizeFitter,是用于调整组件区域使其自适的组件,一般用于与ScrollRect滑动列表以及纵横布局组件搭配,实现动态数量的滑动列表效果,以及与Text组件一起使用,可以根据文字长短进行区域尺寸的变化。