虚幻4渲染编程(工具篇)【第九卷:SlateUI布局】

MY BLOG DIRECTORY:

YivanLee:专题概述及目录

INTRODUCTION:

Slate是跟平台无关的一个UI设计框架,不仅仅可以用来做引擎UI,还可以做引擎编辑器,甚至可以用它来开发其他应用,比如虚幻epic的商城。

一直以来对Unreal的Slate都非常困惑,各种插槽,尺寸,各种布局Panel,最后的UI按键到底尺寸多大感觉难以控制,非常玄学,所以特别研究了一下虚幻的Slate布局。


MAIN CONTENT:

首先需要先知道Slate的设计原理和组织方式。

v2-a6636caa9b3b8b7741eb9bcddf128a98_b.jpg

上图黄色框内的部分是可渲染部分,红色框部分是用于UI布局的部分。SLeafWidget没有插槽,SCompounWidget可以拥有一个插槽,SPanel可以拥有很多插槽。这里需要说明的是可以把插槽理解为一个节点。

v2-754e85910f68175c4f14bebd86685510_b.jpg

下面来几个实际的例子

v2-0b540d4c9774964fe277cd3e20e6cfa0_b.jpg
v2-e8da50278c1717cbc7bda8694b7651fc_b.jpg

可以看到我创建了三个按钮,最上面两个按钮在最下面那个按钮的slot里。一个slot里可以嵌套一个Panel然后这个panel又可以嵌套几个Slot。类似如下结构。SLeafWidget没有插槽,SCompounWidget可以拥有一个插槽,SPanel可以拥有很多插槽。

v2-83a3470532b7aa60568cfe50d3119e8e_b.jpg

正常情况一般不会在按钮上面再嵌套按钮

v2-b4f199945e11cd33ee09b25f7b4cb4fe_b.jpg
v2-db0915160d5622a9b3c521ce4d65f692_b.jpg


扫描二维码关注公众号,回复: 9084360 查看本文章

这个插槽的大小到底占UI空间的多少,取决于很多因素,首先来看SizeParm,这是决定UI控件大小的第一步。

v2-4eb7b613c41814414f43f1ca067093f7_b.jpg

SizeRule有两个策略,一个Stretch一个是Auto

如果我使用Auto,那么Slot大小会使用DesiredSize,如果是stretch那么Slot就会尽可能充满UI空间。

下面是(Auto, fill)的情况

v2-b73181fd786daa5000570f51bb2c347a_b.jpg
v2-696e63d43d9957209f76031e19334fce_b.gif

下面是(stretch, fill)的情况

v2-6aa62312e00e1dc235262cfd79b50126_b.jpg
v2-57d0ca8b3de93d1c0312185b197d47d5_b.gif

不指认的话默认就是stretch。可以看到他们的默认值如下

v2-6293a11e25a3aeaea38665b685d8aae5_b.jpg

可以看到Slot还有个HAlign和VAlign两个参数。这两个参数的作用注释给得很清楚了,就是用来描述Slot的位置的

v2-ddc7cf899b127b7dd63f870047f84f67_b.jpg

当我们使用(Auto,Fill)和(Auto,HAlign_Left)的组合的时候可以看到

v2-4d2ef49fe6cea47839dd33fccde92247_b.jpg

目前只考虑水平方向。首先会看这个Slot的数量和Alignment是那哪种。假设现在有三个Slot并且向这三个slot中添加了一个按钮UI控件,其中两个按钮是(Auto,HAlign_Left),一个按钮是(Fill,Fill_HAlign)的

v2-58313c34bdca964fb5a86720712f5e0e_b.jpg

这个结果的计算过程如下

v2-b59e3716e6ecde237037d07f306dc853_b.jpg

首先有三个插槽,其中两个因为是Auto,所以插槽的大小等于插槽内控件的DesireSize。第一个插槽是stretch,所以它会尽可能延展自己的大小。所以其大小等于窗口的总大小减去其余两个slot占的固定大小。三个插槽的大小准备好以后再往里面填UI控件。因为第一个插槽的填充模式是Fill,所以它会被填满再slot插槽里。剩余的两个插槽里填的控件的填充模式是Left,因为插槽的大小本来就和控件的DesireSize相同,所以后面两个控件刚好能填满后面两个插槽。如果我们把第一个插槽的控件的填充模式缓冲Left

v2-a640b7634ba81c2a15db1483c6a87df1_b.jpg

可以看到因为插槽的大小大于控件自己本身的大小,所以它从开始填充根本填不满整个Slot,所以留下了很多没有被填充的Slot空间。

所以过程大致是先对UI空间进行切割,分割出每个Slot空间的大小,然后再根据不同的UI控件不同的填充模式再把Slot空间进行填充。

如果我三个控件全部选择Auto

v2-5e3d6647a155dee753a785e1af784e81_b.jpg

首先我们有三个Slot,因为都是选用Auto,所以其大小可以被明确计算出来。如果三个Slot里的控件的DesireSize之和小于窗口的大小,那么窗口就会有控件剩余。这时再把控件填充进来,因为是选用的Auto,所以不管控件是什么填充模式,Slot空间的大小始终刚好等于内部控件的大小。

v2-a0485db747f667c6f22e1e4b68954e4c_b.jpg

以上的推导都是建立在控件的大小的总和小于窗口大小下成立,那么当控件的大小总和大于窗口的时候会是什么情况呢

v2-af3ecccd325b76fc55e16ec8fdf4f4d0_b.jpg

因为是Auto,所以Slot的绝对大小不会改变,多余的部分直接会被擦掉。在窗口中的表现就会如下效果所示:

v2-90e8465039f9c93e452d795758c8ecd6_b.gif
v2-5abe81d45e9ac8861a04f917849e7231_b.jpg

最后就是DesiredSize了,前面一直在说这个东西。

v2-49477cc3ac775259713166e9612e8d09_b.png

我们可以找到SBox的计算函数

v2-7f6792b2d3756f7b7cbbf8649f013f64_b.jpg

这个值可以自己定义怎么计算。

反正不管怎么定义计算它就是代表内部控件的大小。即下一个链接节点的大小

v2-3b9c739f415776d93466a66fbb45989b_b.jpg

就SBox这个控件而言可以通过以下变量控制这个DesiredSize

v2-175e618ec75ffb75030395eaa89f051a_b.jpg


剩下的垂直方向上的逻辑和上面讨论的水平方向上的情况是一样的。还有个stretch情况。这种情况就比较简单了,会根据所有的slot的fill百分比进行缩放,我这里直接上代码就不做细致讨论了。

v2-27848c7bb64cfe701f1661287f7331d0_b.jpg




SUMMARY AND OUTLOOK:

至此我们就彻底搞清楚了UI的控件大小布局,如果对UI的细节还不清楚可以先看 @Voron 大佬的文章,文章链接在我的Reference里。我这里只是对控件布局做进一步研究。

个人感觉Slate写UI还是比较简单的,各种东西都封装好了,开发起来也十分方便,甚至可以用它开发其它应用程序。

Enjoy it


NEXT:

todo...


Reference:

【1】zhuanlan.zhihu.com/p/28

发布了384 篇原创文章 · 获赞 4 · 访问量 8050

猜你喜欢

转载自blog.csdn.net/cpongo10/article/details/100745173