设计 GUI

2025年3月17日 | 阅读 12 分钟

现在我们已经完成了基础知识,我们将学习如何使用可重用的 UI 组件构建游戏用户界面 (GUI):生命条、能量条以及炸弹和卢比计数器。

Design the GUI

最终结果

我们还将学习如何

  1. 创建灵活的 UI 组件
  2. 使用场景继承
  3. 构建复杂的 UI

分解 UI

根据最终的 UI 计划,我们将使用的容器。与标题屏幕的设计一样,它以一个 MarginContainer 开始。然后,我们可以看到三个列

  1. 生命条和能量条
  2. 左侧的生命和能量计数器
  3. 右侧的炸弹和卢比计数器

但是条形标签和仪表盘是同一 UI 元素的两个部分。如果我们这样考虑它们,我们剩下两列

  1. 右侧的炸弹和卢比计数器
  2. 左侧的生命和能量条

这样更容易嵌套容器:我们在屏幕边距周围有一些边距,使用边距容器,然后使用 HBoxContainer 来管理我们的两列。在 VBoxContainer 中堆叠两次。我们还需要右侧列中的最后一个 HBoxContainer 来将炸弹和卢比计数器并排显示。

Design the GUI

我们仅用四个容器就获得了清晰的 UI 布局

单个 UI 组件内部需要额外的框,但这为我们提供了主 GUI 场景的结构。有了这个计划,我们就可以进入 Godot 并创建 GUI。

创建基础 GUI

这里有两种可能的 GUI 方法:我们可以设计不同视图中的元素并将它们组合在一起,或者在单个视图中进行原型设计,然后稍后分解。我建议使用一个视图,因为我们可以通过这种方式调整 UI 的放置和快速的比例。一旦看起来不错,我们就可以将节点树的整个部分保存为可重用的子场景。我们稍后会这样做。

现在,让我们从容器开始。

在这里,我们创建一个新场景并添加一个 MarginContainer。选择节点并将其命名为 GUI。之后,将场景保存为 GUI.tscn。它将包含整个 GUI。

在检查器中向下滚动以获取所选的头部和自定义常量部分,该部分用于 MarginContainer。展开它,然后单击每个边距属性旁边的字段。将它们全部设置为 20 像素。接下来,添加一个 HBoxContainer 节点。这个将包含我们左侧的两个条,并在右侧的两个计数器之间分开。

我们必须将条形垂直堆叠在 HBoxContainer 中。让我们添加一个 VBoxContainer。再次选择父级 HBoxContainer,然后添加另一个 HBoxContainer。它将包含一个计数器,所以它被称为计数器。

有了这四个容器,我们就有了 GUI 视图的基础。

Design the GUI

我们应该有四个看起来像这样的容器

注意

我们可以采用这种方法,因为我们首先分解了 UI 设计,并花了几分钟时间考虑我们使用的容器。当我们遵循此类教程时,它可能看起来很奇怪。但是一旦我们处理真实的游戏,我们就会发现这是一个高效的工作流程。

创建条形基础

每个条形被分成两个水平对齐的子元素:左侧带有健康计算的标签,右侧带有仪表盘。同样,HBoxContainer 是合适的工具。选择条形节点并在其内部添加一个新的 HBoxContainer。然后命名它,Bar。

标签至少需要三个节点:一个 NinePatchRect 用于背景,左侧有一个纹理,不是 HP 就是 EP,右侧有一个标签用于显示值。我们可以根据需要嵌套控件节点。我们可以使用 NinePatchRect 作为另外两个元素的父节点,因为它包含了它们。总的来说,我们希望使用容器,因为它们的作用是帮助组织 UI 组件。稍后我们无论如何都需要一个 MarginContainer 来在生命计数和仪表盘之间添加一些空间。选择 Bar 并添加一个 Margincontainer。将其命名为 count。在其内部。添加三个节点

  1. 一个名为 Background 的 NinePatchRect
  2. 一个名为 Title 的 TextureRect
  3. 一个名为 Number 的 Label

要将节点添加为同级节点,请始终先选择 Count 节点。

Design the GUI

我们的场景树应该看起来像这样。我们已准备好放入一些纹理

我们的场景仍然是空的。是时候放入一些组件了。前往左侧的 FileSystem 面板以加载纹理,。浏览 res://assets/GUI 文件夹。

Design the GUI

我们应该看到一个我们将用于皮肤界面的纹理列表。

在 Scene 面板中选择 Background。

在 Inspector 中,我们应该看到一个 texture 属性。在 File-System 选项卡中,将 Label_HP_bg.png 拖放到 Text_Slot。它保持扁平。原始边距以保留最小尺寸,选择背景节点。在 inspector 中,向下滚动到底部。将其设置为最小尺寸 (100,40)。背景应该与我们的原始容器一起调整大小。

接下来,选择 title 并将 label_HP.png 拖放到您的纹理槽中。选择 number 节点,按文本属性旁边的字段,输入 10。这样,我们就可以在视口中看到这两个节点。它们应该堆叠在其父级 MarginContainer 的左上角。

Design the GUI

如果同时选择这两个节点,我们应该看到类似这样的内容

由于它们有一个像直接父级一样的容器,因此我们无法独立移动它们:计数节点将始终重置其锚点、大小和位置。尝试在视口中移动节点并调整它们的大小。然后,选择任何三个纹理节点,按 Ctrl Up 或 Ctrl 重新排序它们在扫描坞中的位置。它们将恢复到以前的形状和位置。

父容器控制其直接子节点的尺寸、缩放、边距和锚点。要修改节点,我们必须将它们嵌套在普通控件或其他 UI 元素中。我们将使用 background 作为 title 和 number 的父节点。选择 title 和 name,然后将它们拖放到 background 上。

Design the GUI

通过使用 background 节点作为两个纹理的父节点,我们保持计数边距远离边距

选择 Title 并在 Inspector 中,将其 stretch mode 属性更改为居中。然后,找到 inspector 中的 rect range 并将 size 属性更改为 (50,40),使其只占据背景的左半部分。然后,选择 number 节点。在视口中,单击 Layout 菜单,然后单击 Full Rectangle。该节点将调整大小以适应背景。在 inspector 旁边的 VAlign 属性,并将其 VAlign 属性更改为 center。文本应吸附到背景右侧的中心。水平调整节点大小,使其占据背景的右半部分,并且右侧有一些填充。

Design the GUI

替换标签的字体

标签的字体太小了。我们需要更改它。选择 number 节点,然后在 inspector 中,滚动到 control 类,找到 custom font 类别。单击 Font 属性旁边的字段,然后单击 New Dynamic Font。再次单击该区域并选择 Edit。

我们将进入动态字体资源。展开 font range 并单击 font data 旁边的字段。单击 Load 按钮。在文件浏览器中,导航到 Asset / Font 文件夹,然后双击 Comfortaa-Bold.ttf 以打开它。我们应该看到字体在视口中更新。展开 settings 类别以更改字体大小。将 size 属性设置为更高的值,例如 2428

现在我们需要 number 的底部边缘,文本的基线,与左侧的 HP 纹理对齐。

要调整文本的基线,再次单击 Custom Font 类别下的 Font 字段,然后调整下面的属性,直到文本与 title 节点对齐。我使用了 2 像素的值。

Design the GUI

使用 2 像素的较低值,数字与标题对齐

至此,我们完成了 GUI 最棘手的部分。

添加

我们需要最后一个元素来完成我们的条形:仪表盘本身。Godot 附带一个 TextureProgress 节点,它包含了我们所需要的一切。

选择条形节点并在其中添加一个 TextureProgress。将其命名为 Gauge。在 inspector 中展开 texture 部分。转到 FileSystem 面板,然后将 lifebar_bg.png 纹理拖放到 underbar 插槽。

仅使用五个 Control 节点,我们的第一个条形就可以使用了。

Design the GUI

设计炸弹和卢比计数器

炸弹和卢比计数器与条形的 count 节点相似。因此,我们将复制它并将其用作模板。

在 bar 节点下,选择 Count 并按 Ctrl D 复制它。将新节点拖放到视口树下的 counters HBoxContainer 下。它应该会自动调整大小。暂时不用担心,我们会很快修复大小。

将 count2 节点命名为 counter。

Design the GUI

选择图标后,在 inspector 中,向上滚动以查看 text 插槽。转到左侧的 FileSystem 面板,然后选择 bomb_icon.png。将其拖放到纹理插槽。在视口中,选择 icon 和 number 节点。单击视口顶部工具栏中的 Layout 菜单,然后选择 Full Rectangle。这两个节点将更新以适应背景大小。

Design the GUI

节点锚定到整个背景,但其位置不对

让我们更改 Number 的对齐属性,将其移动到背景的左侧和中心。选择 Number 节点,并将其 Align 属性更改为 left,VAlign 属性更改为 center。然后稍微调整其左边缘的大小,以便在背景左角和文本之间添加填充。

Design the GUI

Number 节点左对齐并居中

要使图标和背景重叠,我们需要进行一些调整。首先,我们的背景有点长。这是因为它位于一个边距容器内,该容器由最顶层的 GUI 节点控制。

选择视口树顶部的 GUI 节点,并将其垂直收缩,使其尽可能薄。我们将看到仪表盘阻止您将其做得太小。容器的尺寸不能小于其子节点的最小尺寸。容器的边距也有权重。我们将看到仪表盘阻止您将其做得太小。容器的尺寸不能小于其子节点的最小尺寸。容器的边距也有权重。

选择 icon,单击 Layout 菜单,然后选择 Full Rectangle 以再次居中它。我们需要锚定背景的右边缘。再次打开 Layout 菜单,然后选择 Right Center。将 icon 向上移动,使其在环境中垂直居中。

Design the GUI

炸弹图标锚定在背景的右边缘。调整计数器容器的大小,以便从右侧看到图标节点

由于我们复制了带有条形计数器的计数器,因此 number 节点的字体是关闭的。再次选择 Number 节点,转到 Font 属性,然后单击它以访问 Dynamic Font 资源。将 bottom 值更改为 0 以重置字体基线,在 Extra Spacing 部分。我们的计数器现在按预期工作。

既然我们已经做了,我们就来创建它,以便计数器吸附到视口的右边缘。要实现这一点,我们将设置 Bars 容器以扩展并占据所有水平空间。选择 Bars 节点并滚动到 Size Flags 类别。在水平范围中,选中 expansion 值。Bars 节点应该会调整大小并将计数器推到屏幕右侧。

Design the GUI

一个扩展的容器会从其父节点的所有地方延伸出去;它会推开一切。

将条形和计数器转换为可重用的 UI 组件

我们有一个条形和计数器小部件。但我们需要两个。我们以后可能需要更改条形的设计或功能。如果我们有一个视图来存储 UI 元素的模板,并有子视图来处理变体,那将是很好的。Godot 允许我们通过继承的场景来实现这一点。

让我们将计数器和条形分支保存为单独的视图,然后我们将使用它们来创建 LifeBar、EnergyBar、BombCounter 和 Rupee 计数器。选择 bar HBoxContainer。右键单击它,然后单击 Save Branch as a scene。将视图保存为 Bar.tscn。您应该将节点分支更改为单个 bar 节点。

注意
场景是一个节点树。最顶层的节点是树的根,下面的层次结构中的子节点是叶子。根节点以外的任何具有子节点的节点都是一个分支。我们可以将节点分支附加到单独的场景,或者加载它们并将它们合并到一个场景中,从其他场景加载。

然后,选择 counter 节点并执行相同操作。右键单击,将分支保存为场景,并将其保存为 Counter.tscn。场景树中节点右侧会出现一个新的编辑场景图标。单击条形旁边的图标以打开相应的场景。调整条形节点的大小,使其边界框适合其内容。我们放置 name 和 control 节点的方式,我们已准备好继承此模板并创建生命条。计数器也是如此。

Design the GUI

我们的条形已经准备好使用,并进行了其他更改

使用视觉继承创建其余元素

我们需要两个工作方式相同的条形:它们应该在左侧有一个标签,带有某个值,并在右侧有一个水平仪表盘。唯一的区别是,一个标有 HP 且为绿色,而另一个标有 EP 且为黄色。Godot 为我们提供了一个强大的工具来创建所有条形在游戏中重用的通用基础

继承的场景

Design the GUI

内置场景有助于保持 GUI 场景整洁。最终,我们只会拥有容器和一个 UI 组件的节点。

在继承场景中,您可以保留检查器中每个节点的任何属性,与其名称分开。如果您修改并保存原始场景,所有底层场景都会更新以反映更改。如果您在继承场景中更改了值,它将始终覆盖父属性。这对于 UI 很有用,因为它们通常需要对类似元素进行更改。总的来说,UI 设计、按钮、面板等共享一个通用的基本样式和交互。我们不想手动将其复制到所有变体中。

一个重新加载图标将出现在您覆盖的属性旁边。单击此按钮可将值重置为原始场景的默认值。

注意
将视觉继承视为节点树,或 GDScriptextends 关键字的扩展。继承的场景会像其父节点一样执行所有操作,但您可以覆盖属性、资源并添加其他节点和脚本来增强其功能。

进入条形场景以创建 LifeBar

转到 Scene -> New Inherited Scene 以创建一种新型条形。选择条形场景并打开它。您应该会看到一个新的 [unsaved] 标签,与您的条形类似,但根节点除外的所有节点都显示为灰色。按 Meta + S 保存新继承的场景,并将其命名为 LifeBar。

Design the GUI

我们不能重命名灰色节点。它告诉您它们有一个父场景

首先,将根节点或顶层节点重命名为 LifeBar。我们总是希望根节点准确地描述此 UI 组件。这个名称将此条形与我们接下来要创建的 EnergyBar 区分开来。视图内的其他节点必须用更通用的术语来描述组件的结构,以便它适用于所有继承的步骤。就像我们的 TextureProgress 和 number 节点一样。

注意
如果您曾经做过网页设计,它感觉就像使用 CSS 一样:您创建一个基本类,并使用修饰符类添加变体。从基本按钮类中,用户将获得 button-green 和 button-red 变体来接受和拒绝提示。新类具有父元素的名称和一个新关键字来解释它如何修改。当我们创建一个继承场景并更改顶层节点的名称时,我们就是在做同样的事情。