文章

UE5 Create a Simple Game

入门

下载起始项目并解压缩。转到项目文件夹并打开InfiniteMatrix.uproject

播放测试运动控制。可以通过移动鼠标进行垂直和水平移动。

img

你要做的第一件事就是让玩家不断前进。

Moving the Player Forward

导航到Blueprints文件夹并打开BP_Player

要向前移动玩家,将在每一帧中为玩家的位置添加一个偏移量。

首先,需要创建一个变量来定义玩家向前移动的速度。创建一个名为ForwardSpeed的 Float变量并将其默认值设置为2000

img

接下来,确保位于事件图表中,然后找到Event Tick节点。创建以下设置:

img

通过将ForwardSpeedDelta Seconds相乘,将获得与帧速率无关的结果。

注意:如果不熟悉帧速率独立性,请阅读我们的蓝图教程。我们在帧速率独立性部分介绍了它。

接下来,将使用此结果沿单个轴移动玩家。

沿单轴移动

要移动玩家,请创建一个AddActorWorldOffset节点。通过左键单击复选框将 Sweep设置为true

img

如果尝试将Float结果连接到Delta Location输入,Unreal 会自动将其转换为Vector

img

但是,这会将 Float 值放入 Vector 的 X、Y 和 Z 分量中。

对于这个游戏,向前移动应该只沿着X 轴

幸运的是,可以将一个 Vector 拆分为三个Float组件。

  • 确保AddActorWorldOffset节点的Delta Location引脚没有连接。

  • 右键单击 Delta Location引脚并选择Split Struct Pin

img

最后,像这样连接一切:

img

让我们回顾一下:

  1. 每一帧,游戏都会将ForwardSpeedDelta Seconds相乘以获得与帧速率无关的结果
  2. AddActorWorldOffset将使用结果沿 X 轴移动玩家
  3. 由于启用了Sweep,如果有任何东西阻挡玩家将停止前进

单击编译,然后返回到主编辑器。如果你按下Play,你将穿过隧道。

img

可以创建一个自动生成隧道的蓝图,而不是手动放置隧道。

创建隧道生成器

转到 Content Browser 并确保位于Blueprints文件夹中。

Actor作为父类创建一个新的蓝图类,将其命名为 BP_TunnelSpawner 然后打开它。

由于游戏会不断生成隧道,因此创建一个生成函数是个好主意。

转到 My Blueprint 面板并创建一个名为SpawnTunnel的新函数。此功能的目的是在提供的位置生成隧道。

要将位置传递给函数,函数需要一个输入参数。当调用该函数时,这些将显示为输入引脚。

img

它们还将在函数的入口节点上显示为输出引脚。

img

让我们继续创建一个输入参数。确保位于SpawnTunnel函数的图表中。选择Entry节点,然后转到 Details 面板。单击“输入”部分旁边的+号。

img

将输入参数重命名为SpawnLocation并将其类型更改为Vector

img

要生成隧道,请添加一个Spawn Actor From Class节点。单击位于Class引脚右侧的下拉菜单并选择BP_Tunnel

img

要设置生成位置,请右键单击 Spawn Transform引脚并选择Split Struct Pin

然后,将Spawn Actor From Class节点链接到Entry节点,如下所示:

img

现在,无论何时调用SpawnTunnel函数,它都会在提供的位置生成一个BP_Tunnel实例。

让我们测试一下!

测试隧道生成器

切换到 Event Graph 并找到Event BeginPlay节点。添加一个SpawnTunnel节点并将其连接到Event BeginPlay节点。

SpawnTunnel节点上,将Spawn Location设置为(2000, 0, 500)

img

现在,当游戏开始时,它会在远离玩家的地方生成一条隧道。单击编译,然后返回到主编辑器。

首先,从关卡中删除BP_Tunnel 。 通过左键单击World Outliner 中的BP_Tunnel来执行此操作。然后,按Delete键将其从关卡中删除。

接下来,转到内容浏览器。左键单击并将BP_TunnelSpawner 拖到 视口中。这会将它的一个实例添加到关卡中。

如果按下Play,游戏将在玩家上方和远离玩家的地方生成一条隧道。

img

完成测试后,返回BP_TunnelSpawner将SpawnTunnel节点的Spawn Location重置为(0, 0, 0)

然后,单击编译,然后返回到主编辑器。

在下一节中,将为BP_Tunnel设置功能。

设置隧道蓝图

BP_Tunnel将负责两件事。第一个是检测游戏何时应生成新隧道。为此,将创建一个触发区域。一旦触发,BP_Tunnel将告诉BP_TunnelSpawner生成一个新隧道。通过这样做,可以创造出无尽隧道的错觉。

img

它要做的第二件事是定义一个重生点。然后BP_TunnelSpawner将使用此点作为下一个生成位置。

让我们从创建触发区开始。

创建触发区

打开BP_Tunnel,然后转到 Components 面板。添加一个Box Collision组件并将其命名为TriggerZone

目前碰撞区域很小。转到“详细信息”面板并找到“形状”部分。将Box Extent属性设置为(32, 500, 500)

img

接下来,将Location属性设置为(2532, 0, 0)。这会将TriggerZone放置在隧道网格的末端。这意味着新隧道只会在玩家到达隧道尽头时生成。

img

现在,是时候创建重生点了

创建重生点

要定义生成点的位置,可以使用场景组件。这些组件非常适合定义位置,因为它们只包含一个转换。它们在视口中也可见,因此可以看到重生点的位置。

转到“组件”面板并确保没有选择任何内容。添加一个Scene组件并将其重命名为SpawnPoint

img

隧道网格在X 轴上的长度为 2500 个单位,因此应该是附加点所在的位置。转到 Details 面板并将Location属性设置为(2500, 0, 0)

img

接下来要做的是创建一个在SpawnPoint生成隧道的函数。

Spawning Tunnels at the Spawn Point

单击Compile,然后切换到BP_TunnelSpawner

下一个BP_Tunnel应该在最远隧道的SpawnPoint处生成。通过这样做,隧道将始终继续。

img

由于最远的隧道始终是最后生成的隧道,因此可以轻松获得对它的引用。

打开SpawnTunnel的图表。右键单击 Spawn Actor From Class节点的Return Value引脚。选择Promote to Variable并将变量重命名为NewestTunnel

img

现在,将始终参考最远的隧道。

接下来,创建一个新函数并将其命名为SpawnTunnelAtSpawnPoint

创建以下图形:

img

此设置将获取最新的隧道及其SpawnPoint组件的位置。然后它会在这个位置产生一个新的隧道。

为了让BP_Tunnel与 BP_TunnelSpawner通信,它需要一个引用。

如果没有通信,BP_TunnelSpawner将不知道何时生成下一个隧道。

创建对 Tunnel Spawner 的引用

单击Compile,然后关闭SpawnTunnelAtSpawnPoint图。之后,切换到BP_Tunnel

添加一个新变量并将其命名为TunnelSpawner。将其变量类型设置为BP_TunnelSpawner\Object Reference

img

单击Compile,然后切换回BP_TunnelSpawner

打开SpawnTunnel的图表并添加指示的节点:

img

现在,每个隧道都将引用BP_TunnelSpawner

接下来,将告诉BP_TunnelSpawner在玩家进入TriggerZone时生成下一个隧道。

编写触发区脚本

单击Compile,然后切换到BP_Tunnel

转到 Components 面板并右键单击TriggerZone。选择添加事件\添加 OnComponentBeginOverlap。这会将以下节点添加到的事件图表中:

img

只要另一个Actor与 TriggerZone重叠,该节点就会执行。

首先,应该检查与TriggerZone重叠的Actor是否是玩家。

左键单击拖动**Other Actor引脚。在空白区域上松开鼠标左键,然后从菜单中选择Cast to BP_Player 。

img

注意:由于一条隧道在另一条隧道的尽头生成,它会触发该隧道的TriggerZone如果Other Actor是隧道,则转换为 BP_Player将阻止任何进一步的节点执行。

接下来,在Cast to BP_Player节点后添加指示的节点:

img

让我们逐步完成:

  1. Actor与 TriggerZone重叠时,On Component Begin Overlap (TriggerZone)节点将执行
  2. Cast to BP_Player节点检查重叠的 Actor 是否是玩家
  3. 如果是玩家,那么BP_TunnelSpawner将生成一个新的隧道。它的位置将在最后生成的隧道的SpawnPoint组件中。
  4. 由于旧隧道不再使用,游戏使用DestroyActor节点将其移除

点击Compile,回到主编辑器然后点击Play。一旦你到达隧道的尽头,游戏就会产生一个新的隧道。

img

尽管游戏中不断地生成隧道,但它看起来并不是无穷无尽的。可以通过始终显示一些隧道来缓解这种情况。稍后,当将其与障碍物结合使用时,玩家将看不到生成的隧道。

生成更多隧道

首先要做的是创建一个生成一定数量隧道的函数。

打开BP_TunnelSpawner并创建一个名为 SpawnInitialTunnels的新函数。

要生成指定数量的隧道,可以使用ForLoop节点。该节点将执行连接的节点指定的次数。

添加一个ForLoop节点并将其连接到Entry节点。

img

要使ForLoop节点执行n次,需要将Last Index设置为n – 1

在本教程中,将生成三个隧道。要执行三个循环,请将Last Index值设置为2

img

注意:如果不设置First IndexLast Index字段,它们将默认为0

游戏开始时,玩家应始终从隧道开始。为此,可以在玩家所在位置生成第一条隧道。

产生第一个隧道

要确定第一个隧道是否已生成,可以检查是否设置了NewestTunnel 。

如果未设置,则表示第一个隧道尚未生成。这是因为NewestTunnel仅在游戏生成隧道设置。

要执行此检查,请在ForLoop节点之后添加一个 IsValid节点(带有问号图标的节点)。

接下来,获取对NewestTunnel 的引用并将其连接到IsValid节点的输入对象引脚。

img

如果未设置NewestTunnel ,则 Is Not Valid pin 将执行,反之亦然。

添加以下内容并将其连接到IsValid节点的Is Not Valid引脚:

img

此设置将在玩家 Pawn 的位置生成一条隧道。

接下来,将生成后续隧道。

生成后续隧道

添加一个SpawnTunnelAtSpawnPoint节点并将其连接到IsValid节点的Is Valid引脚。

img

这是最终图表:

img

概括:

  1. ForLoop节点一共会执行三次
  2. 在第一个循环中,它会在玩家所在位置生成一条隧道
  3. 在随后的循环中,它将在最新隧道的SpawnPoint处生成一个隧道

接下来,转到事件图表并删除SpawnTunnel节点。然后,在Event BeginPlay之后添加一个 SpawnInitialTunnels节点。

img

现在,当游戏开始时,它会产生三个隧道。

点击Compile,回到主编辑器然后点击Play。隧道现在更长了!

img

游戏目前不是很有挑战性,所以让我们添加一些障碍。

制造障碍

以下是将用作障碍物的网格:

img

打开BP_Tunnel并转到 Components 面板。添加一个静态网格组件并将其命名为WallMesh

转到 Details 面板并将其Static Mesh属性更改为SM_Hole_01

接下来,将其Location属性设置为(2470, 0, 0)。这会将它放在隧道的尽头。

img

为了让游戏更有趣,墙壁也会旋转。添加一个新的Float变量并将其命名为RotateSpeed将默认值设置为30

切换到 Event Graph 并找到Event Tick节点。创建以下设置:

img

这将使WallMesh按提供的量旋转每一帧。

单击编译,然后返回到主编辑器。按播放键查看旋转的墙壁。

img

让我们通过在墙壁上添加一些变化来增加趣味性。

创建墙壁变化

无需为每个变体创建新的蓝图,只需随机化WallMesh即可。

打开BP_Tunnel并创建一个名为 RandomizeWall的新函数。之后,创建以下图形:

img

顾名思义,Set Static Mesh节点会将 WallMesh设置为提供的网格。

要制作静态网格列表,可以使用选择节点。

左键单击拖动 New Mesh引脚。释放左键单击空白区域,然后添加一个选择节点。

img

选择节点允许设置选项列表。Index输入确定Select节点输出 选项。

由于有四个墙壁网格可用,需要再创建两个选项引脚。可以通过右键单击 Select节点并选择Add Option Pin来执行此操作。这样做直到你有四个选项引脚。

img

接下来,将每个选项设置为以下内容:

  • 选项 0: SM_Hole_01
  • 选项 1: SM_Hole_02
  • 选项 2: SM_Hole_03
  • 选项 3: SM_Hole_04

img

现在,让我们选择一个随机选项。

随机化墙

可以使用范围节点中的随机整数来获取随机数。该节点将返回一个>= Min 且 <= Max的值。

在 Range 节点中添加一个Random Integer并将其连接到Select节点的Index引脚。

img

最大值设置为3。这将为提供四个可能的数字:0、1、2 和 3。

img

为了创建更多的随机化,让我们向WallMesh添加随机旋转。在Set Static Mesh节点后添加以下内容:

img

这将为WallMesh添加 0360度之间的随机旋转。

这是最终图表:

img

概括:

  1. 选择节点提供网格列表
  2. 使用范围节点中的随机整数选择随机网格
  3. Set Static Mesh节点将WallMesh设置为选定的网格
  4. AddLocalRotation节点向WallMesh添加随机旋转偏移

单击Compile,然后关闭RandomizeWall图。

切换到BP_TunnelSpawner并打开SpawnTunnel图。添加高亮节点:

img

现在,每当隧道生成时,它都会有一个随机的墙体网格。

关闭SpawnTunnel图,然后单击Compile。返回主编辑器并按“播放”以查看所有的墙变体!

img

如果你撞到墙,你将停止前进。然而,如果你四处走动并穿过一个洞,你将再次开始前进。

下一步是在玩家与墙壁碰撞时禁用向前移动。

处理墙壁碰撞

要启用或禁用向前移动,可以使用布尔变量。这些只有两种状态:truefalse

打开BP_Player,然后创建一个名为IsDead的新 布尔变量。

接下来,转到Event Tick节点并创建一个Branch节点。

然后,获取对IsDead 的引用并将其连接到Branch节点的Condition引脚。

img

Event Tick节点连接到Branch节点。然后,将Branch节点的False引脚连接到AddActorWorldOffset节点。

img

现在,只要IsDead设置为true,玩家就会停止前进。

接下来,让我们在玩家撞墙时设置IsDead变量。

设置 IsDead 变量

单击Compile,然后切换到BP_Tunnel。在“组件”面板中,右键单击WallMesh选择“添加事件\添加 OnComponentHit”。这会将以下节点添加到的事件图表中:

img

只要另一个ActorWallMesh发生碰撞,该节点就会执行。

首先,需要检查与WallMesh发生碰撞的Actor是否是玩家。

左键单击拖动 Other Actor引脚。在空白区域上松开鼠标左键,然后从菜单中选择Cast to BP_Player 。

img

接下来,左键单击拖动**Cast 到 BP_Player节点的BP_Player引脚。释放左键单击空白区域,然后添加一个Set Is Dead节点。

通过左键单击 复选框IsDead设置为true

img

单击编译,然后返回到主编辑器。按播放并尝试撞墙。如果你绕到一个洞,你将不再穿过它。

img

在下一节中,将在玩家撞墙时显示一个重新启动按钮。

显示重启按钮

将显示的Widget为WBP_Restart可以在UI文件夹中找到它。这是它的样子:

img

要显示或隐藏小部件,需要对它的引用。打开BP_Player,然后创建一个名为RestartWidget的新变量。将变量类型更改为WBP_Restart\Object Reference

img

接下来,转到 Event Graph 并找到Event BeginPlay节点。

添加一个Create Widget节点并将Class值设置为WBP_Restart

然后,添加一个Set Restart Widget节点,然后像这样连接所有内容:

img

现在,当玩家生成时,它将创建WBP_Restart的一个实例。下一步是制作一个显示此实例的函数。

创建显示功能

创建一个新函数并将其命名为DisplayRestart。完成后,创建以下图表:

img

概括:

  1. 添加到视口将在屏幕上显示RestartWidget
  2. 设置仅输入模式 UI将限制玩家与 UI 的交互。这是为了让玩家在死后无法四处走动。
  3. 顾名思义,Set Show Mouse Cursor只是显示鼠标光标

要显示重启按钮,需要做的就是在播放器与墙壁碰撞后调用DisplayRestart 。

调用显示函数

关闭DisplayRestart图,然后单击Compile

切换到BP_Tunnel,然后找到On Component Hit (WallMesh)节点。

DisplayRestart节点添加到节点链的末尾。

img

单击Compile,然后关闭BP_Tunnel。返回主编辑器并按Play。如果撞墙,就会出现重启按钮。

img

最后一步是在玩家单击按钮时重新启动游戏。

重启游戏

重启时游戏需要做两件事:

  1. 重置播放器。这包括从屏幕上移除重启按钮。
  2. 重生隧道。这样玩家就可以从隧道的起点开始。

让我们从重置播放器开始。

重置播放器

打开BP_Player,然后创建一个名为RestartGame的新函数。创建以下图形:

img

概括:

  1. Set Is Dead将 IsDead设置为false。这将重新启用向前运动。
  2. Remove From Parent从屏幕上移除RestartWidget
  3. 设置输入模式游戏仅重新启用游戏输入,以便玩家可以四处移动
  4. 设置 Show Mouse Cursor隐藏鼠标光标

接下来,让我们重生隧道。

重生隧道

单击Compile,然后关闭BP_Player

打开BP_TunnelSpawner并确保位于SpawnInitialTunnels图中。

首先,需要在生成新隧道之前移除现有隧道。

在Entry节点之后添加一个Sequence节点。将Then 1引脚连接到ForLoop节点。

img

注意:**Sequence节点按顺序执行其输出。这是垂直组织图表的好方法,尤其是因为节点链可能会变得很长。

接下来,创建以下节点:

img

此设置将获取所有现有隧道并将它们从游戏中移除。

最后,将Sequence节点的Then 0引脚连接到Get All Actors of Class节点。这将确保隧道在产卵过程之前被移除。

这是最终图表:

img

最后要做的是处理按钮点击。

处理按钮点击

单击Compile,然后关闭BP_TunnelSpawner

转到内容浏览器并导航到UI文件夹。双击WBP_Restart将其打开

选择RestartButton,然后转到“详细信息”面板。转到事件部分并单击OnClicked旁边的按钮

img

这将创建一个名为On Clicked (RestartButton)的节点。当玩家点击RestartButton时,该节点将执行。

重新创建以下内容:

img

概括:

  1. Get Owning Player Pawn返回玩家当前控制的 Pawn
  2. 转换为 BP_Player检查 Pawn 是否属于BP_Player类
  3. 如果是,它将调用RestartGame函数。此函数重置播放器并隐藏重启按钮。
  4. Get All Actors of ClassGet返回BP_TunnelSpawner,然后调用SpawnInitialTunnels。此函数将删除现有隧道并生成新隧道。

注意:可能想知道为什么我使用Get All Actors Of Class而不是使用对 BP_TunnelSpawner的引用。主要原因是因为BP_Tunnel与 WBP_Restart没有关系。对于像这样的简单游戏,执行上述方法比弄清楚在哪里存储引用更容易。

单击编译,然后关闭蓝图编辑器。按播放键测试重启按钮!

img

本文由作者按照 CC BY 4.0 进行授权