UE5 Create a Simple Game
入门
下载起始项目并解压缩。转到项目文件夹并打开InfiniteMatrix.uproject。
按播放测试运动控制。可以通过移动鼠标进行垂直和水平移动。
你要做的第一件事就是让玩家不断前进。
Moving the Player Forward
导航到Blueprints文件夹并打开BP_Player。
要向前移动玩家,将在每一帧中为玩家的位置添加一个偏移量。
首先,需要创建一个变量来定义玩家向前移动的速度。创建一个名为ForwardSpeed的 Float变量并将其默认值设置为2000。
接下来,确保位于事件图表中,然后找到Event Tick节点。创建以下设置:
通过将ForwardSpeed与Delta Seconds相乘,将获得与帧速率无关的结果。
注意:如果不熟悉帧速率独立性,请阅读我们的蓝图教程。我们在帧速率独立性部分介绍了它。
接下来,将使用此结果沿单个轴移动玩家。
沿单轴移动
要移动玩家,请创建一个AddActorWorldOffset节点。通过左键单击其复选框将 Sweep设置为true。
如果尝试将Float结果连接到Delta Location输入,Unreal 会自动将其转换为Vector。
但是,这会将 Float 值放入 Vector 的 X、Y 和 Z 分量中。
对于这个游戏,向前移动应该只沿着X 轴。
幸运的是,可以将一个 Vector 拆分为三个Float组件。
确保AddActorWorldOffset节点的Delta Location引脚没有连接。
右键单击 Delta Location引脚并选择Split Struct Pin。
最后,像这样连接一切:
让我们回顾一下:
- 每一帧,游戏都会将ForwardSpeed和Delta Seconds相乘以获得与帧速率无关的结果
- AddActorWorldOffset将使用结果沿 X 轴移动玩家
- 由于启用了Sweep,如果有任何东西阻挡玩家将停止前进
单击编译,然后返回到主编辑器。如果你按下Play,你将穿过隧道。
可以创建一个自动生成隧道的蓝图,而不是手动放置隧道。
创建隧道生成器
转到 Content Browser 并确保位于Blueprints文件夹中。
以Actor作为父类创建一个新的蓝图类,将其命名为 BP_TunnelSpawner 然后打开它。
由于游戏会不断生成隧道,因此创建一个生成函数是个好主意。
转到 My Blueprint 面板并创建一个名为SpawnTunnel的新函数。此功能的目的是在提供的位置生成隧道。
要将位置传递给函数,函数需要一个输入参数。当调用该函数时,这些将显示为输入引脚。
它们还将在函数的入口节点上显示为输出引脚。
让我们继续创建一个输入参数。确保位于SpawnTunnel函数的图表中。选择Entry节点,然后转到 Details 面板。单击“输入”部分旁边的+号。
将输入参数重命名为SpawnLocation并将其类型更改为Vector。
要生成隧道,请添加一个Spawn Actor From Class节点。单击位于Class引脚右侧的下拉菜单并选择BP_Tunnel。
要设置生成位置,请右键单击 Spawn Transform引脚并选择Split Struct Pin。
然后,将Spawn Actor From Class节点链接到Entry节点,如下所示:
现在,无论何时调用SpawnTunnel函数,它都会在提供的位置生成一个BP_Tunnel实例。
让我们测试一下!
测试隧道生成器
切换到 Event Graph 并找到Event BeginPlay节点。添加一个SpawnTunnel节点并将其连接到Event BeginPlay节点。
在SpawnTunnel节点上,将Spawn Location设置为(2000, 0, 500)。
现在,当游戏开始时,它会在远离玩家的地方生成一条隧道。单击编译,然后返回到主编辑器。
首先,从关卡中删除BP_Tunnel 。 通过左键单击World Outliner 中的BP_Tunnel来执行此操作。然后,按Delete键将其从关卡中删除。
接下来,转到内容浏览器。左键单击并将BP_TunnelSpawner 拖到 视口中。这会将它的一个实例添加到关卡中。
如果按下Play,游戏将在玩家上方和远离玩家的地方生成一条隧道。
完成测试后,返回BP_TunnelSpawner。将SpawnTunnel节点的Spawn Location重置为(0, 0, 0)。
然后,单击编译,然后返回到主编辑器。
在下一节中,将为BP_Tunnel设置功能。
设置隧道蓝图
BP_Tunnel将负责两件事。第一个是检测游戏何时应生成新隧道。为此,将创建一个触发区域。一旦触发,BP_Tunnel将告诉BP_TunnelSpawner生成一个新隧道。通过这样做,可以创造出无尽隧道的错觉。
它要做的第二件事是定义一个重生点。然后BP_TunnelSpawner将使用此点作为下一个生成位置。
让我们从创建触发区开始。
创建触发区
打开BP_Tunnel,然后转到 Components 面板。添加一个Box Collision组件并将其命名为TriggerZone。
目前碰撞区域很小。转到“详细信息”面板并找到“形状”部分。将Box Extent属性设置为(32, 500, 500)。
接下来,将Location属性设置为(2532, 0, 0)。这会将TriggerZone放置在隧道网格的末端。这意味着新隧道只会在玩家到达隧道尽头时生成。
现在,是时候创建重生点了
创建重生点
要定义生成点的位置,可以使用场景组件。这些组件非常适合定义位置,因为它们只包含一个转换。它们在视口中也可见,因此可以看到重生点的位置。
转到“组件”面板并确保没有选择任何内容。添加一个Scene组件并将其重命名为SpawnPoint。
隧道网格在X 轴上的长度为 2500 个单位,因此应该是附加点所在的位置。转到 Details 面板并将Location属性设置为(2500, 0, 0)。
接下来要做的是创建一个在SpawnPoint生成隧道的函数。
Spawning Tunnels at the Spawn Point
单击Compile,然后切换到BP_TunnelSpawner。
下一个BP_Tunnel应该在最远隧道的SpawnPoint处生成。通过这样做,隧道将始终继续。
由于最远的隧道始终是最后生成的隧道,因此可以轻松获得对它的引用。
打开SpawnTunnel的图表。右键单击 Spawn Actor From Class节点的Return Value引脚。选择Promote to Variable并将变量重命名为NewestTunnel。
现在,将始终参考最远的隧道。
接下来,创建一个新函数并将其命名为SpawnTunnelAtSpawnPoint。
创建以下图形:
此设置将获取最新的隧道及其SpawnPoint组件的位置。然后它会在这个位置产生一个新的隧道。
为了让BP_Tunnel与 BP_TunnelSpawner通信,它需要一个引用。
如果没有通信,BP_TunnelSpawner将不知道何时生成下一个隧道。
创建对 Tunnel Spawner 的引用
单击Compile,然后关闭SpawnTunnelAtSpawnPoint图。之后,切换到BP_Tunnel。
添加一个新变量并将其命名为TunnelSpawner。将其变量类型设置为BP_TunnelSpawner\Object Reference。
单击Compile,然后切换回BP_TunnelSpawner。
打开SpawnTunnel的图表并添加指示的节点:
现在,每个隧道都将引用BP_TunnelSpawner。
接下来,将告诉BP_TunnelSpawner在玩家进入TriggerZone时生成下一个隧道。
编写触发区脚本
单击Compile,然后切换到BP_Tunnel。
转到 Components 面板并右键单击TriggerZone。选择添加事件\添加 OnComponentBeginOverlap。这会将以下节点添加到的事件图表中:
只要另一个Actor与 TriggerZone重叠,该节点就会执行。
首先,应该检查与TriggerZone重叠的Actor是否是玩家。
左键单击并拖动**Other Actor引脚。在空白区域上松开鼠标左键,然后从菜单中选择Cast to BP_Player 。
注意:由于一条隧道在另一条隧道的尽头生成,它会触发该隧道的TriggerZone。如果Other Actor是隧道,则转换为 BP_Player将阻止任何进一步的节点执行。
接下来,在Cast to BP_Player节点后添加指示的节点:
让我们逐步完成:
- 当Actor与 TriggerZone重叠时,On Component Begin Overlap (TriggerZone)节点将执行
- Cast to BP_Player节点检查重叠的 Actor 是否是玩家
- 如果是玩家,那么BP_TunnelSpawner将生成一个新的隧道。它的位置将在最后生成的隧道的SpawnPoint组件中。
- 由于旧隧道不再使用,游戏使用DestroyActor节点将其移除
点击Compile,回到主编辑器然后点击Play。一旦你到达隧道的尽头,游戏就会产生一个新的隧道。
尽管游戏中不断地生成隧道,但它看起来并不是无穷无尽的。可以通过始终显示一些隧道来缓解这种情况。稍后,当将其与障碍物结合使用时,玩家将看不到生成的隧道。
生成更多隧道
首先要做的是创建一个生成一定数量隧道的函数。
打开BP_TunnelSpawner并创建一个名为 SpawnInitialTunnels的新函数。
要生成指定数量的隧道,可以使用ForLoop节点。该节点将执行连接的节点指定的次数。
添加一个ForLoop节点并将其连接到Entry节点。
要使ForLoop节点执行n次,需要将Last Index设置为n – 1。
在本教程中,将生成三个隧道。要执行三个循环,请将Last Index值设置为2。
注意:如果不设置First Index或Last Index字段,它们将默认为0
游戏开始时,玩家应始终从隧道开始。为此,可以在玩家所在位置生成第一条隧道。
产生第一个隧道
要确定第一个隧道是否已生成,可以检查是否设置了NewestTunnel 。
如果未设置,则表示第一个隧道尚未生成。这是因为NewestTunnel仅在游戏生成隧道后设置。
要执行此检查,请在ForLoop节点之后添加一个 IsValid节点(带有问号图标的节点)。
接下来,获取对NewestTunnel 的引用并将其连接到IsValid节点的输入对象引脚。
如果未设置NewestTunnel ,则 Is Not Valid pin 将执行,反之亦然。
添加以下内容并将其连接到IsValid节点的Is Not Valid引脚:
此设置将在玩家 Pawn 的位置生成一条隧道。
接下来,将生成后续隧道。
生成后续隧道
添加一个SpawnTunnelAtSpawnPoint节点并将其连接到IsValid节点的Is Valid引脚。
这是最终图表:
概括:
- ForLoop节点一共会执行三次
- 在第一个循环中,它会在玩家所在位置生成一条隧道
- 在随后的循环中,它将在最新隧道的SpawnPoint处生成一个隧道
接下来,转到事件图表并删除SpawnTunnel节点。然后,在Event BeginPlay之后添加一个 SpawnInitialTunnels节点。
现在,当游戏开始时,它会产生三个隧道。
点击Compile,回到主编辑器然后点击Play。隧道现在更长了!
游戏目前不是很有挑战性,所以让我们添加一些障碍。
制造障碍
以下是将用作障碍物的网格:
打开BP_Tunnel并转到 Components 面板。添加一个静态网格组件并将其命名为WallMesh。
转到 Details 面板并将其Static Mesh属性更改为SM_Hole_01。
接下来,将其Location属性设置为(2470, 0, 0)。这会将它放在隧道的尽头。
为了让游戏更有趣,墙壁也会旋转。添加一个新的Float变量并将其命名为RotateSpeed。将默认值设置为30。
切换到 Event Graph 并找到Event Tick节点。创建以下设置:
这将使WallMesh按提供的量旋转每一帧。
单击编译,然后返回到主编辑器。按播放键查看旋转的墙壁。
让我们通过在墙壁上添加一些变化来增加趣味性。
创建墙壁变化
无需为每个变体创建新的蓝图,只需随机化WallMesh即可。
打开BP_Tunnel并创建一个名为 RandomizeWall的新函数。之后,创建以下图形:
顾名思义,Set Static Mesh节点会将 WallMesh设置为提供的网格。
要制作静态网格列表,可以使用选择节点。
左键单击并拖动 New Mesh引脚。释放左键单击空白区域,然后添加一个选择节点。
选择节点允许设置选项列表。Index输入确定Select节点输出 的选项。
由于有四个墙壁网格可用,需要再创建两个选项引脚。可以通过右键单击 Select节点并选择Add Option Pin来执行此操作。这样做直到你有四个选项引脚。
接下来,将每个选项设置为以下内容:
- 选项 0: SM_Hole_01
- 选项 1: SM_Hole_02
- 选项 2: SM_Hole_03
- 选项 3: SM_Hole_04
现在,让我们选择一个随机选项。
随机化墙
可以使用范围节点中的随机整数来获取随机数。该节点将返回一个>= Min 且 <= Max的值。
在 Range 节点中添加一个Random Integer并将其连接到Select节点的Index引脚。
将最大值设置为3。这将为提供四个可能的数字:0、1、2 和 3。
为了创建更多的随机化,让我们向WallMesh添加随机旋转。在Set Static Mesh节点后添加以下内容:
这将为WallMesh添加 0到360度之间的随机旋转。
这是最终图表:
概括:
- 选择节点提供网格列表
- 使用范围节点中的随机整数选择随机网格
- Set Static Mesh节点将WallMesh设置为选定的网格
- AddLocalRotation节点向WallMesh添加随机旋转偏移
单击Compile,然后关闭RandomizeWall图。
切换到BP_TunnelSpawner并打开SpawnTunnel图。添加高亮节点:
现在,每当隧道生成时,它都会有一个随机的墙体网格。
关闭SpawnTunnel图,然后单击Compile。返回主编辑器并按“播放”以查看所有的墙变体!
如果你撞到墙,你将停止前进。然而,如果你四处走动并穿过一个洞,你将再次开始前进。
下一步是在玩家与墙壁碰撞时禁用向前移动。
处理墙壁碰撞
要启用或禁用向前移动,可以使用布尔变量。这些只有两种状态:true和false。
打开BP_Player,然后创建一个名为IsDead的新 布尔变量。
接下来,转到Event Tick节点并创建一个Branch节点。
然后,获取对IsDead 的引用并将其连接到Branch节点的Condition引脚。
将Event Tick节点连接到Branch节点。然后,将Branch节点的False引脚连接到AddActorWorldOffset节点。
现在,只要IsDead设置为true,玩家就会停止前进。
接下来,让我们在玩家撞墙时设置IsDead变量。
设置 IsDead 变量
单击Compile,然后切换到BP_Tunnel。在“组件”面板中,右键单击WallMesh并选择“添加事件\添加 OnComponentHit”。这会将以下节点添加到的事件图表中:
只要另一个Actor与WallMesh发生碰撞,该节点就会执行。
首先,需要检查与WallMesh发生碰撞的Actor是否是玩家。
左键单击并拖动 Other Actor引脚。在空白区域上松开鼠标左键,然后从菜单中选择Cast to BP_Player 。
接下来,左键单击并拖动**Cast 到 BP_Player节点的BP_Player引脚。释放左键单击空白区域,然后添加一个Set Is Dead节点。
通过左键单击 复选框将IsDead设置为true。
单击编译,然后返回到主编辑器。按播放并尝试撞墙。如果你绕到一个洞,你将不再穿过它。
在下一节中,将在玩家撞墙时显示一个重新启动按钮。
显示重启按钮
将显示的Widget为WBP_Restart。可以在UI文件夹中找到它。这是它的样子:
要显示或隐藏小部件,需要对它的引用。打开BP_Player,然后创建一个名为RestartWidget的新变量。将变量类型更改为WBP_Restart\Object Reference。
接下来,转到 Event Graph 并找到Event BeginPlay节点。
添加一个Create Widget节点并将Class值设置为WBP_Restart。
然后,添加一个Set Restart Widget节点,然后像这样连接所有内容:
现在,当玩家生成时,它将创建WBP_Restart的一个实例。下一步是制作一个显示此实例的函数。
创建显示功能
创建一个新函数并将其命名为DisplayRestart。完成后,创建以下图表:
概括:
- 添加到视口将在屏幕上显示RestartWidget
- 设置仅输入模式 UI将限制玩家与 UI 的交互。这是为了让玩家在死后无法四处走动。
- 顾名思义,Set Show Mouse Cursor只是显示鼠标光标
要显示重启按钮,需要做的就是在播放器与墙壁碰撞后调用DisplayRestart 。
调用显示函数
关闭DisplayRestart图,然后单击Compile。
切换到BP_Tunnel,然后找到On Component Hit (WallMesh)节点。
将DisplayRestart节点添加到节点链的末尾。
单击Compile,然后关闭BP_Tunnel。返回主编辑器并按Play。如果撞墙,就会出现重启按钮。
最后一步是在玩家单击按钮时重新启动游戏。
重启游戏
重启时游戏需要做两件事:
- 重置播放器。这包括从屏幕上移除重启按钮。
- 重生隧道。这样玩家就可以从隧道的起点开始。
让我们从重置播放器开始。
重置播放器
打开BP_Player,然后创建一个名为RestartGame的新函数。创建以下图形:
概括:
- Set Is Dead将 IsDead设置为false。这将重新启用向前运动。
- Remove From Parent从屏幕上移除RestartWidget
- 设置输入模式游戏仅重新启用游戏输入,以便玩家可以四处移动
- 设置 Show Mouse Cursor隐藏鼠标光标
接下来,让我们重生隧道。
重生隧道
单击Compile,然后关闭BP_Player。
打开BP_TunnelSpawner并确保位于SpawnInitialTunnels图中。
首先,需要在生成新隧道之前移除现有隧道。
在Entry节点之后添加一个Sequence节点。将Then 1引脚连接到ForLoop节点。
注意:**Sequence节点按顺序执行其输出。这是垂直组织图表的好方法,尤其是因为节点链可能会变得很长。
接下来,创建以下节点:
此设置将获取所有现有隧道并将它们从游戏中移除。
最后,将Sequence节点的Then 0引脚连接到Get All Actors of Class节点。这将确保隧道在产卵过程之前被移除。
这是最终图表:
最后要做的是处理按钮点击。
处理按钮点击
单击Compile,然后关闭BP_TunnelSpawner。
转到内容浏览器并导航到UI文件夹。双击WBP_Restart将其打开。
选择RestartButton,然后转到“详细信息”面板。转到事件部分并单击OnClicked旁边的按钮。
这将创建一个名为On Clicked (RestartButton)的节点。当玩家点击RestartButton时,该节点将执行。
重新创建以下内容:
概括:
- Get Owning Player Pawn返回玩家当前控制的 Pawn
- 转换为 BP_Player检查 Pawn 是否属于BP_Player类
- 如果是,它将调用RestartGame函数。此函数重置播放器并隐藏重启按钮。
- Get All Actors of Class并Get返回BP_TunnelSpawner,然后调用SpawnInitialTunnels。此函数将删除现有隧道并生成新隧道。
注意:可能想知道为什么我使用Get All Actors Of Class而不是使用对 BP_TunnelSpawner的引用。主要原因是因为BP_Tunnel与 WBP_Restart没有关系。对于像这样的简单游戏,执行上述方法比弄清楚在哪里存储引用更容易。
单击编译,然后关闭蓝图编辑器。按播放键测试重启按钮!