一、基本概念
UMG与Slate:虚幻图形界面设计器(Unreal Motion Graphics UI Designer)(UMG)为 UI编辑工具,可以用来创建UI元素,布局和UI动画。此编辑器下每一个控件对应一个U版控件。U版的控件仅仅是Slate控件的容器,Slate控件是真正执行控件逻辑(包括渲染和事件)的地方。从代码中可以看到一个U版控件总会包含一个S版的控件指针,如UImage中的TSharedPtr<SImage> MyImage。UWidget为所有U版控件的基类,SWidget为所有S版控件的基类。
二、控件树
控件树代表了控件的树状父子关系,UI的最终尺寸和布局由自己的尺寸及其兄弟UI和父子UI决定。根据子控件个数,SWiget共有三个子类:SLeafWidget(无子控件),SComponentWidget(一个子控件),SPanel(多个子控件)。对应U版分别举例为:UImage,UButton,UCanvasPanel。如果一定要Button拥有多个子控件,可以嵌套一个Panel。
三、Slot,布局最关键的一步
决定布局的最关键属性。Slot的类型由父控件(容器)决定,并不是自己的属性。即:把一个控件拖进容器内,则有对应的Slot属性,如图2所示。下面以Canvas Panel Slot、Overlay Slot和VerticalBox Slot为例讲述Slot的各属性条目,布入的控件为Image(Image控件以本控件代称,父控件以容器代称)。其中前两种容器,多个子控件间没有布局排版,仅有上下级关系;后者有多个子控件的排版。
图2 同一控件在不同容器下的Slot
1.CanvasPanelSlot:排版最为自由的Slot
Anchors:锚点。Anchors类型表示了本控件在容器中的对齐控件和方法,如图3所示。当选择图3红框中的锚点类型时,为非填充模式,修饰字段为Position和Size(如图4左所示),分别表示基于锚点(左中右上中下)的位置和控件的大小;当选中非红框中的锚点类型,为填充模式,以绿框为例,Y方向上变为OffsetTop和OffsetBottom,表示距顶边和底边的距离(如图4右所示)。
图3 Anchors类型
图4 不同Anchors类型的修饰字段
Alignment:校准。坐标代表这个点在本控件上的位置,(0,0)代表左上角 (1,1)代表右下角。总之是一个与本控件大小有关的值,给个具体情况感受一下就懂了(图5)。
图5 Alignment示例
SizeToContent:由子控件(容器的子控件,即本控件)决定最终的大小。如图6所示,Image的Size为32X32,勾选SizeToContent后Slot的SizeXY失效,最终大小为Image的Size。注意:父控件为SizeToContent,子控件为Fill是错误的用法。
图6 左侧不勾选SizeToContent,右侧勾选
PS:活用此属性可实现类似聊天框的效果,如图7所示。
图7 父控件勾选了SizeToContent,其大小由子控件TextBlock决定
ZOrder:兄弟控件间的层级关系,不是一个绝对值。当兄弟控件处于同一层级,上下关系会由控件树的顺序及渲染时的合批等其他因素决定。
2.OverlaySlot:极尽简约。
与Canvas不同,没有锚点,仅仅可选择水平与竖直方向上的对齐(或填充)方式;没有Size,大小完全由子控件决定;也没有ZOrder,上下层级关系靠控件树中子控件的顺序。
Padding:即控件的边缘大小。可以理解为控件在本身大小的基础上又在周围增加了一圈大小。注意,根据Slate代码容器在计算布局时会先扣除所有的Padding再进行布局,谨防控件本身被Padding挤压,这一点VBox还会讲。一图感受以上所有属性(图8)。
图8 OverlaySlot的一些属性
3.VerticalBoxSlot:排版真正开始。
VerticalBox在横向上与Overlay相似,控件单享所有的横向控件,因此横向布局不再赘述;纵向上兄弟控件瓜分所有空间,顺序为控件树中从上到下。此时Size中有Auto和Fill选项,顾名思义,Auto为使用子控件的大小,Fill为填充。布局规则(仅讨论VerticalBox为固定大小,非SizeToContent)为:首先,扣除所有子控件的Padding,剩余尺寸继续排版;然后,剩余尺寸扣除所有Size为Auto的大小,再剩余尺寸进行填充;最后,剩余尺寸根据Fill后的归一化数值进行分配,如果此时没有Fill的控件多余的尺寸会空出来。Fill的尺寸为该控件尺寸Fill值/所有Fill值的累加。各种情况如图9-10所示。
图9 容器中所有控件为Auto,有未分配的空间
图10 Size为Fill时的情况
需要特别注意Size的Fill和Alignment的对齐与填充的区别。一句话概括,Size是你从容器中得到的空间,Alignment是如何对你得到空间的最后分配。如图11所示,通过Size的Fill获得了容器的全部空间,但是对齐方式和Image本身的大小只使用了其中的一部分。
图11 Size和Alignment的关系
四、可见性、裁剪和RenderTransform
简单来讲,控件的Visibility枚举中仅有Collapsed会清除该控件的排版;裁剪框与布局无关,仅会在渲染时将超出的部分剔除,如图12所示;RenderTransform也不会改变布局,仅会在最后的渲染中应用变换,如图13所示。
图12 左侧为裁剪,右侧为不裁剪
图13 RenderTransform对布局没有影响
五、文字的换行
如图14所示,不勾选AutoWrap不会自动换行,勾选后会;对于英文,WrappingPolicy选择Allow Per Character Wrapping会逐字符换行,貌似其他语言还没有非逐字符换行的功能。但是为什么我没有逐字符换行呢?版本4.26
图14 文字换行
六、DPI(更新中)
不是很懂,读懂了给大伙分享。应该能找到不少资料→
https://zhuanlan.zhihu.com/p/100618893
七、简单示例和一些技巧(什么教宗更新视频了,那我一会再写)
UP并没有UI排版经验,仅分享一些我的想法,贻笑大方了。总的来说,在UI不太复杂的情况下,大的静态布局采用Canvas足矣;小的动态布局或者一些规律性布局使用Vertical/HorizontalBox或Grid。在使用VerticalBox等的时候,最好将同一类控件放在一个VerticalBox下,并且该类控件封装成另一个蓝图控件以方便管理。总体效果如图15所示
图15 UI布局示例