UE5 UI
入门
下载起始项目并解压缩。转到项目文件夹并打开GeometryCatcher.uproject。
按播放键控制一个白色立方体并尝试接住掉落的形状。可以通过移动鼠标水平移动捕手。十秒后,形状将停止生成。
要做的第一件事是创建一个显示两件事的 HUD:
- 一个记录玩家收集了多少形状的计数器
- 一个计时器,显示在形状停止生成之前还剩多少秒
要创建所有这些,需要使用widget。
关于Widgets
widget 是为 UI 提供某种视觉功能的 UI 元素。例如,Button widget提供了一个用户可以看到并单击的对象。
widget本身不必是可见的。例如,网格面板widget在其内容之间平均划分空间。用户看不到网格面板,但可以看到它的效果。
widget还可以包含其他widget。以下是包含文本widget(名称标签)和文本框widget的自定义widget的示例:
甚至可以将widget构建为整个界面,例如菜单屏幕。下面是一个看起来像标题屏幕的widget示例。
所有 UI 元素也是widget,并包含在标题屏幕widget中。
现在知道什么是widget,是时候为 HUD 创建一个widget了。
创建一个widget
转到内容浏览器并导航到UI文件夹。单击Add New按钮并选择User Interface\Widget Blueprint。将新资产重命名为WBP_HUD。
双击WBP_HUD以在UMG UI Designer 中将其打开。
UMG 用户界面设计师
UMG UI Designer 由七个主要元素组成:
- Designer 设计器:此区域包含widget的可视化表示。按住右键并移动鼠标进行平移。滚动 鼠标滚轮进行缩放。
- Details 详细信息:选择的任何widget都将在此处显示其属性
- Palette 调色板:可以使用的所有widget的列表。任何用户创建的widget也将出现在这里。
- Hierarchy 层次结构:当前使用的所有widget的列表
- Animations 动画:widget可以使某些属性具有动画效果,例如位置和大小。该面板列出了所有的动画。
- Timeline 时间轴:当选择动画时,此面板将显示动画属性和关键帧
- Editor Mode 编辑器模式:在这里,可以在设计器模式和图形模式之间切换。图表模式几乎与蓝图的事件图表相同。
创建文本widget
文本widget非常适合显示数字信息,例如计数器和计时器。
UE5中需要先创建 Canvas Panel
转到调色板面板并搜索文本widget。通过按住左键单击并将其拖到设计器面板中来添加widget。
暂时不要担心文本内容,稍后会替换它。
将widget重命名为CounterText。可以通过选择文本widget并转到详细信息面板来执行此操作。在位于顶部的文本框中输入CounterText 。
可以通过左键单击并拖动设计器中的widget来移动widget。
还可以通过左键单击并拖动手柄来调整小部件的大小。调整大小允许设置widget的范围。Unreal 不会渲染边界外的任何东西。
或者,可以通过修改“详细信息”面板中的值来设置位置和大小。为CounterText设置以下属性和值:
- 位置 X: 200
- Y 位置: 50
- X 码: 500
- Y 码: 100
目前,文本只占框的一小部分。
可以通过转到“详细信息”面板并导航到“外观”部分来增加字体大小。在Font属性的最右侧,有一个用于设置字体大小的文本框。
将字体大小设置为68。
让我们通过在它旁边添加一个图标来使计数器看起来更好。
创建图像widget
图像widget是一种在 UI 中显示图形(例如图标)的简便方法。
创建一个Imagewidget并将其命名为CounterIcon。将位置 X设置为75,将位置 Y 设置为50。这会将它放在CounterText旁边。
要设置图像,请转到“详细信息”面板并转到“外观”部分。展开Brush属性,然后单击Image的下拉列表。选择T_Counter。
图像看起来会被拉伸,因为widget的尺寸与图像不同。
除了调整widget的大小,还可以使用“调整内容大小”选项。此选项将自动调整widget的大小以适应其内容。
仍在 Details 面板中,转到Slot(Canvas Panel Slot)部分。选中Size To Content旁边的复选框。
该widget将自行调整大小以适合图像。
在不同尺寸的屏幕上玩游戏时,UI 需要相应地移动其widget。要维护 UI 的布局,可以使用锚点。
锚点
锚点定义widget的位置相对于何处。默认情况下,widget将其锚点设置在其父级的左上角。因此,当设置widget的位置时,实际上是在设置它相对于该锚点的位置。
在下面的示例中,每个图像都锚定到一个点(最近的角)。
注意每个图像如何保持其相对于其锚点的位置。使用锚点,可以确保的 UI 在不同的屏幕尺寸上具有相同的布局。
还可以使用锚点自动调整widget的大小。当锚定到两个或更多点时,widget将自行调整大小以保持其相对大小。
在下面的示例中,该栏锚定在左上角和右上角。
在垂直方向上,条会移动但不会调整大小。这是因为它在 Y 轴(顶部)上只有一个锚点。
但是,条形会水平调整大小,因为它在 X 轴上有两个锚点。
Anchor Medallion代表锚点的位置。只要选择了一个widget,它就会出现。
CounterText和CounterIcon的锚点已经在正确的位置,因此无需设置它们。
接下来,将为计时器创建另一个文本和图像widget。但是,这次会将它们放在右侧。
创建定时器
创建一个文本widget并将其命名为TimerText。设置以下属性:
- X位置: 1225
- Y 位置: 50
- X 码: 500
- Y 码: 100
- 字号: 68
- 理由:对齐文本右(这会将文本对齐到widget的右侧)
接下来,将锚点设置在右上角。可以通过左键单击并拖动 Anchor Medallion上的圆圈来完成此操作。将锚奖章移动到右上角。
注意位置是如何更新为相对于锚点的。
创建一个图像widget并将其命名为TimerIcon。设置以下属性:
- X位置: 1750
- Y 位置: 50
- 内容大小:选中
- 画笔\图像: T_Timer
可以使用预设,而不是使用 Anchor Medallion 设置锚点。转到 Details 面板并单击Anchors旁边的下拉菜单以显示预设。
选择第三个预设(右上角有方块的那个)。
UI 的布局现已完成。
可以通过模拟不同的屏幕尺寸来查看锚点的工作情况。转到 Designer 面板并单击Screen Size 下拉菜单。
选择一个选项将更改WBP_HUD的大小以匹配该选项。下面是 HUD 在 iPad Air 上的样子。注意widget是如何靠得更近的。
在下一节中,将学习如何显示WBP_HUDwidget。
显示 HUD
单击编译,然后返回到主编辑器。导航至Blueprints文件夹并双击BP_GameManager将其打开。
游戏一开始,HUD 就应该可见。可以使用Event BeginPlay节点来执行此操作。
找到Event BeginPlay节点,然后将Create Widget节点添加到节点链的末尾。该节点将创建指定widget的实例。
单击类旁边的下拉列表并选择WBP_HUD。
要显示 HUD,需要使用添加到视口节点。左键单击并拖动 Create Widget节点的Return Value引脚。
释放左键单击空白区域以显示上下文菜单。添加一个添加到视口节点。
让我们回顾一下事件的顺序:
- 一旦 Unreal 生成BP_GameManager,就会执行Restart和SetUpCamera函数。这些函数设置了一些变量和相机。如果不知道函数是什么,请不要担心。本教程稍后将介绍它们。
- Create Widget节点创建 WBP_HUD的实例
- 添加到视口节点显示WBP_HUD
单击编译,然后返回到主编辑器。按Play以使用新的 HUD 玩游戏。
要显示计数器和计时器的值,需要保存该信息的变量。可以在BP_GameManager中找到这些变量。
要使用这些变量,需要一种从WBP_HUD访问BP_GameManager 的方法。可以通过在变量中存储对BP_GameManager 的引用来实现。
存储引用
存储引用很有用,因为这意味着可以轻松访问特定实例。
想象一下,你有一个盒子,里面有一个球。如果你想找到球并检查它,那很容易,因为只有一个盒子。
现在,假设有一百个盒子,但只有一个盒子装着一个球。必须检查每个盒子,直到找到装有球的盒子。
每当想检查球时,都必须执行此操作。这将很快导致性能问题。
使用参考,可以跟踪装有球的盒子。这样,就不必选中每个框。
创建变量
打开WBP_HUD并通过转到 Editor Mode 并选择Graph切换到 Graph 模式。
导航到 My Blueprint 选项卡并创建一个名为GameManager的新变量。
转到 Details 面板并单击Variable Type旁边的下拉菜单。搜索BP_GameManager并选择BP Game Manager\Object Reference。
设置参考
点击Compile然后打开BP_GameManager。
找到Create Widget节点,然后左键单击并拖动 Return Value引脚。释放左键单击空白区域,然后从菜单中选择“设置游戏管理器” 。
然后,将Add to Viewport节点链接到Set Game Manager节点。
注意:可以通过双击它们来重新布线以创建一个Reroute节点。左键单击并 拖动 Reroute节点以重新布线。
接下来,创建一个Self节点并将其连接到Set Game Manager节点的左侧引脚。Self节点将列为Get a reference to self。
现在,当创建WBP_HUD时,它将引用BP_GameManager。
在下一节中,将学习如何借助函数更新Widget。
蓝图函数 - Functions
在蓝图中,函数是类似于事件图的图。与事件图不同,可以使用节点调用函数。但是你为什么要这样做呢?
Organization
使用函数的原因之一是结构化。通过使用函数,可以将多个节点合并为一个节点。
查看BP_GameManager的Event BeginPlay部分。有两个函数:Restart和SetUpCamera。
这是没有函数的部分的样子:
如所见,使用函数看起来更简洁。
Reusability - 可重用性
使用函数的另一个原因是可重用性。
例如,如果想重置计数器和计时器,可以使用Restart函数轻松完成。
这为节省了每次要重置这些变量时都必须重新创建节点的工作。
既然知道函数是什么,将使用一个函数来更新CounterTextwidget。
更新widget
默认情况下,无法从蓝图中访问文本widget。这意味着将无法设置它们的 Text 属性。幸运的是,这是一个简单的修复。
单击编译,然后打开WBP_HUD。切换到 Designer 模式。
选择CounterText,然后转到“详细信息”面板。选中位于最顶部的Is Variable 复选框。
现在,将能够更新CounterText。下一步是创建一个函数来更新文本。
创建更新函数
切换回图形模式,然后转到“我的蓝图”选项卡。单击Functions部分右侧的+号。
这将创建一个新函数并将带到它的图表。将函数重命名为UpdateCounterText。
默认情况下,图形将包含一个Entry节点。当函数执行时,这就是它开始的地方。
要使CounterText显示ShapesCollected变量,需要链接它们。
将GameManager变量拖到图中。左键单击并拖动其引脚,然后在空白处释放左键单击。从菜单中选择获取收集的形状。
要设置文本,将使用SetText (Text)节点。将CounterText变量拖到图中。左键单击并拖动其引脚,然后在空白处释放左键单击。从菜单中,添加一个SetText (Text)节点。
SetText (Text)只接受 Text类型的输入。但是,ShapesCollected变量的类型为Integer。幸运的是,当尝试将Integer插入Text输入时,Unreal 会自动进行转换。
将ShapesCollected变量连接到设置文本 (Text)节点的In Text引脚。Unreal 会自动为创建ToText (int)节点。
要完成该功能,请将Entry节点连接到Set Text(文本)节点。
事件顺序:
- 当调用UpdateCounterText时,该函数将从 BP_GameManager获取ShapesCollected变量
- ToText (int)节点将 ShapesCollected的值转换为Text类型
- SetText (Text)会将 CounterText的文本设置为ToText (int)的值
接下来要做的是每当玩家收集到形状时调用UpdateCounterText 。
调用更新函数
调用UpdateCounterText 的最佳位置是在游戏增量ShapesCollected之后。我创建了一个名为IncrementShapesCollected 的函数,它可以为递增计数器。只要形状与玩家重叠,它们就会调用此函数。
单击Compile,然后返回BP_GameManager。
在调用UpdateCounterText之前,需要引用WBP_HUD。看看你是否可以自己存储一个引用!
- 找到创建和显示WBP_HUD 的部分。
- 左键单击并拖动 Create Widget节点的Return Value引脚。
- 释放左键单击空白区域,然后从菜单中选择“提升为变量” 。
- 将新节点添加到节点链的末尾
创建变量后,将其重命名为HUDWidget。
接下来,拖动单击 Set HUDWidget节点的右侧引脚并在空白处释放。添加一个UpdateCounterText节点。这将确保CounterText在游戏开始时显示ShapesCollected的值。
然后,导航到“我的蓝图”面板并转到“功能”部分。双击IncrementShapesCollected打开它的图表。
将HUDWidget变量拖到图表中。左键单击拖动其引脚并在空白处释放。添加一个UpdateCounterText节点并像这样连接它:
现在,无论何时执行IncrementShapesCollected,它都会递增ShapesCollected,然后调用UpdateCounterText。然后此函数会将CounterText更新为 ShapesCollected的值。
点击Compile然后关闭BP_GameManager。按播放并收集一些形状以查看CounterTextwidget更新。
接下来,将使用称为绑定的不同方法更新TimerTextwidget。
绑定
绑定允许自动更新某些widget属性。要可绑定,该属性必须具有绑定下拉列表。
可以将属性绑定到widget中包含的函数或变量。绑定会不断地从函数或变量中获取一个值。然后它将绑定属性设置为该值。
可能想知道为什么不应该一直使用绑定。绑定效率低下,因为它们不断更新。
这意味着即使没有任何新信息,游戏也会浪费时间更新属性。将其与之前的方法进行比较,其中widget仅在需要时更新。
话虽如此,绑定非常适合经常更改的元素,例如计时器。让我们继续为TimerText创建一个绑定。
创建绑定
打开WBP_HUD并切换到设计器模式。
选择TimerText,然后转到“详细信息”面板中的“内容”部分。将看到Text属性是可绑定的。单击Bind 下拉菜单并选择Create Binding。
这将为创建一个新函数并将带到它的图表。将函数重命名为UpdateTimerText。
该函数将有一个Return节点,其Return Value pin 类型为Text。TimerText将显示插入此引脚的任何文本。
将GameManager拖到图中,然后从中获取TimeRemaining变量。
将TimeRemaining变量连接到返回节点的返回值。和上次一样,Unreal 会自动为你添加一个转换节点。
概括:
- 绑定会不断调用UpdateTimerText函数
- 该函数将从BP_GameManager获取 TimeRemaining变量
- ToText (浮动)节点会将值从TimeRemaining转换为文本类型。
- 然后将转换后的值输出到Return节点
HUD 终于完成了。单击Compile,然后关闭WBP_HUD。按播放查看最终结果。