UMG源码笔记
整理下最近学习UE4 UMG的进度。
1.UMG类视图
UMG 控件跟Unity UGUI不太一样,不是所有的控件节点,都能拥有子节点,为了区分这三种控件,整理了下他们基类:
- UWidget : 所有UMG 控件的公共基类,不提供增加子节点功能
- UPanelWidget : 提供了增加子节点功能,可以有多个子节点
- UContentWidget : 继承于UPanelWidget,是UPanelWidget的一种特例,只能有一个子节点
UMG常用控件的继承关系如下图所示:
1.1 不能有子节点的控件如下:
这个类别的控件的公共基类都是UWidget,每个UMG控件,都持有一个Slate控件的智能指针。
1.2 可以增加子节点的控件:
1.2.1 可以有一个子节点控件
有一个子节点的控件继承的父类依次是 UComponentWidget -> UPanelWidget,父类UComponentWidget构造函数中设置了不允许多个孩子标记位:
UContentWidget::UContentWidget(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
bCanHaveMultipleChildren = false;
}
公共基类UPanelWidget定义了AddChild函数,可以增加对应的子节点:
UPanelSlot* UPanelWidget::AddChild(UWidget* Content)
{
if ( Content == nullptr )
{
return nullptr;
}
if ( !bCanHaveMultipleChildren && GetChildrenCount() > 0 )
{
return nullptr;
}
Content->RemoveFromParent();
EObjectFlags NewObjectFlags = RF_Transactional;
if (HasAnyFlags(RF_Transient))
{
NewObjectFlags |= RF_Transient;
}
UPanelSlot* PanelSlot = NewObject<UPanelSlot>(this, GetSlotClass(), NAME_None, NewObjectFlags);
PanelSlot->Content = Content;
PanelSlot->Parent = this;
Content->Slot = PanelSlot;
Slots.Add(PanelSlot);
OnSlotAdded(PanelSlot);
InvalidateLayoutAndVolatility();
return PanelSlot;
}
其中,GetSlotClass返回对应控件的Slot的类型,在类视图里,带红色方格的标记的,是各自控件GetSlotClass返回的Slot的类型。Slot会分别指向父节点跟子节点。
1.2.2 可以有多个子节点控件
1.3 Slate控件类视图
Slate中除了SWidget之外有三个基础类,其他控件都是继承者三个基类。
- SPanel : 有多个子节点
- SLeafWidget : 没有子节点
- SCompoundWidget : 可以有一个子节点
2 UMG渲染流程
TODO