虚幻引擎-UMG技巧和窍门

技巧1:容器小部件

容器小部件只占用其内部最大内容的布局空间

在UMG中,我通常看到两种小部件:一种是占用布局空间的小部件,如图像/文本;另一种是容纳这些小部件的容器,如网格/覆盖/水平和垂直框。注意:Canvas(画布)是一个奇怪的小部件,我通常在所有布局中忽略它,直到最后。要掌握UMG设计,只需记住容器的大小将取决于其内部最大的小部件。

container.gif

这里的网格容器只和内部最大的内容一样大,所以它最初是0x0像素,然后当图标被打开时,网格变为256x256像素大小,即使打开一个较小尺寸的图像,它仍然保持256x256,因为布局取决于内部最大的内容。我也将网格容器用作更智能的覆盖层,很少使用行/列功能。

大多数时候,当我工作时,我会看到许多复杂的布局,包括多个尺寸框和嵌套在另一个画布中的画布,以及所有其他试图控制布局大小的方法。这些布局变得脆弱且过于复杂(性能也很差),因为设计师/程序员在与UMG的核心设计理念作斗争,即容器的大小取决于其内部最大的内容。这非常像网页设计和div,div的大小只取决于它渲染的屏幕百分比或div内部占用空间的最大内容。

以下是我经常使用的一些小部件示例:

容器小部件 - 网格
- 覆盖
- 水平框
- 垂直框
- 缩放框

布局空间小部件

- 图像
- 文本
- 进度条
- 按钮
- 间隔
- 尺寸框

垂直框和水平框略有不同,它们的布局空间是内部内容在垂直Y轴或水平X轴上的总和

containerVertical.gif

这里的垂直框容器的大小是所有内部对象Y高度的总和,所以它最初是0x0像素,然后当图标被打开时,它变为256x256像素大小,接着打开一个较小尺寸的图像,它仍然保持256x256 + 128x128,所以现在容器的大小是256 + 128的Y和256的X。
容器现在的大小是:256x384

技巧2:负边距

既然容器的大小取决于其内部的图像/文本,那么如何绕过2的幂次纹理呢?负边距应该允许你调整布局大小并保持布局空间。

下一个要解决的难题是,如果你在UMG中使用2的幂次纹理(这可能是你应该做的),并且你有一个按钮,其点击区域是这个纹理,而纹理有空白区域且没有紧贴边缘?技巧是使用负边距来补偿纹理中的空白区域。

我有一个用Photoshop制作的PNG按钮,然后我将其放入网格容器中的按钮小部件中,现在它的点击区域比按钮本身大得多:

amorphButton.png
hitarea.png

为了在布局中修复这个问题,我将使用负边距来使整个容器更紧密地围绕512x512的2的幂次按钮纹理。

首先,我将展示如何在Photoshop中精确测量点击区域:

96DPI.png
redHitArea.png

你需要确保你的Photoshop文档是96 DPI,这很重要,因为SLATE是96DPI,而不是72,因此你的像素坐标在72 DPI下不会100%准确。这对你的布局意味着什么?如果你在72 DPI的Photoshop中将字体大小设置为33pt,那么在96 DPI的Unreal中,你需要设置的字体大小将不同,33pt在72 DPI下相当于24.75pt。这也适用于像素精确的锚点,比如如果你知道在Photoshop文件中从文档边缘向上100像素的位置,为了在编辑器中实现相同的效果,你需要在Photoshop文件中使用96 DPI来匹配编辑器。这不会影响图像或纹理,它们不需要是96 DPI(但我仍然这样做,因为Photoshop文件设置为96 DPI)。行业标准是72 DPI的图像,如果你知道为了获得像素精确的准确性,你需要将Photoshop文件更改为96 DPI,但保持相同的大小(例如1920x1080保持相同大小但更改为96 DPI),你应该没问题。

希望这是一个很好的总结,来自一位匿名开发者:

“在Photoshop中使用96 DPI的目标是能够准确测量像素[从Photoshop到UMG]”

确保我的文档是96 DPI后,我想测量左下角和右上角的宽度/高度以获得点击区域的尺寸:

topRight.png
bottomLeft.png

现在,当我回到按钮的边距设置时,我可以输入这些负值:

negativePadding.png

现在我的容器大小与Photoshop中的点击区域完全一致:

containerSizeNegativePadding.png

因此,如果我将这个小部件嵌套在另一个小部件中并水平堆叠它们,它们会稍微重叠,因为Unreal认为UMG小部件的大小只与其容器大小相同……由于负边距,它的大小小于512x512纹理。但如果你没有负边距,那么你将无法获得紧密贴合的小部件,反而可能会尝试强制使用缩放框、尺寸框或画布大小来抵消纹理的空白区域。这会消耗更多的性能,所以掌握负边距并更好地控制UMG布局。

noFlush.png
soFlush.png

技巧3:网格面板非常有用 - 优先使用网格而不是画布

网格是UMG中最有用的小部件

我在Twitter上有一个关于网格与画布的讨论,因为网格是非常有用的小部件,通过微调图层,你可以用它们做很多疯狂而伟大的事情。我基本上只是复制我在Twitter上发布的内容,但网格允许你操纵哪些内容会或不会占用布局空间,并且允许你通过z-order高效地分层内容。

iconGrid1.jpg

布局如下:

网格面板(总大小256x256)

  • 背景图像(256x256)
  • 图标图像(256 x 256)
  • 水平框(对齐右上角并微调)

    钻石图像(32x32)
    钻石图像(32x32)
    钻石图像(32x32)

  • 文本(对齐右下角并微调)

在我的水平框槽中,我将其对齐到右上角,然后我将其微调为X轴-30和Y轴20,使其完美地坐在那个角落:

iconGrid2.jpg

对于文本,我做了类似的事情,但我将其对齐到右下角,并在X轴20和Y轴30处微调,使其超出容器。

iconGrid3.jpg

然而,当你使用网格容器进行微调时,你不会占用布局空间,因此当我在水平框中加载它们时,我的“2”非常贴合:

IconGrid4.jpg

这也是我如何让图标延伸到背景边框之外的方法,我向上和向左微调负值,现在我有一个动态布局,始终是256x256,但超出布局计算的是我的“2”文本位置和图标剑的顶部位置。

iconGridNudge.jpg
iconGridNudge2.jpg

将网格用作更智能的覆盖小部件,你可以通过图层独立控制z排序,并且可以使用微调和对齐将任何内容放置在网格小部件的内部/甚至外部。

技巧4:使用“包裹为”/“替换为”

UMG有一个方便的“包裹为”和“替换为”功能,经常使用它来尝试布局中的新内容

UMG布局是一个不断试验和错误的过程,通过包裹/替换容器来测试你的布局。因此,经常使用方便的“包裹为/替换为”功能,以保持相同的槽设置,但快速有效地尝试不同的容器。

当你想删除一个小部件时,使用“替换为子项”:

replaceWithChild.png

我可以轻松地替换我的画布和缩放框,而不会太严重地破坏我的布局,并且非常有效地工作:

replaceWithChild.gif

同样适用于“包裹为”和“替换为”,你可以快速更改任何类型的布局容器以使用你想要的内容:

replaceWithHorizontal.png
replaceWithHorizontal_result.png

使用这些功能应该能快速加快你的工作流程,并允许你快速调整布局,测试各种容器和布局。

技巧5:何时使用渲染变换

渲染变换非常有用,当你想缩放/调整大小/旋转/枢轴某物但不想改变布局大小时。

UMG有一个有用的设置叫做渲染变换,这是UMG希望你用来进行动画的。但它们也可以用于修改布局而不改变渲染布局比例。例如,这里我有一个布局,我想放大这个我制作的材质图像:

renderScale12.png

我可以尝试通过更改图像大小来缩放它:

imageSize.gif

但这最终会缩放我的整个小部件大小,因为容器的大小只取决于其内部最大的内容。同样,使用缩放框尺寸框也会如此,因为这些小部件占用布局空间,因此如果我以这种方式放大图像,我的布局会变得更大。

scaleBoxSize.gif

通过缩放框设置为用户指定大小进行缩放

然后,当然,人们会想使用画布小部件进行缩放,但这并不必要,因为UMG有一种方法可以在不改变布局的情况下缩放/旋转/平移内容,那就是通过渲染变换。因此,如果我通过渲染变换缩放这个图像,UMG“认为”它的图像大小是512x512,在布局大小计算中,它实际上是以1024x1024渲染的。

renderTransform.gif

RenderTransforms.png

这也是UMG序列器动画的工作方式,它们使用相同的变换,因此你可以进行动画而不改变布局/位置。这一切都回到了解UMG的布局计算,你的容器大小是多少?你需要使用渲染变换来避免改变容器大小吗?或者你希望你的小部件占用布局空间?掌握何时以及何时不希望对象占用布局空间将使你能够更快地创建更灵活和模块化的UMG布局。