UE-简单游戏

 学习内容 

  • 连续向前移动玩家
  • 生成玩家必须避开的障碍物
  • 随机化障碍以创造变化
  • 创建一个在玩家遇到障碍物时显示的重启按钮

入门

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

注意:如果您收到一条消息说项目是使用早期版本的虚幻编辑器创建的,那没关系(引擎经常更新)。您可以选择打开副本的选项,也可以选择就地转换的选项。

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

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

让角色向前移动

导航到Blueprints文件夹并打开BP_Player

要将Player向前移动,您将在每帧的Player位置上添加一个偏移量。

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

接下来,确保您在 Event Graph 中,然后找到Event Tick节点。创建以下设置:

通过将ForwardSpeed与Delta Seconds相乘,您可以获得与帧速率无关的结果

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

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

沿单轴移动

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

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

但是,这会将 Float 值放入 Vector 的 X、Y 和 Z 分量中。对于这个游戏,向前移动应该只沿着X 轴。幸运的是,您可以将 Vector 拆分为三个Float组件

确保AddActorWorldOffset节点的Delta Location引脚没有连接右键单击Delta Location引脚并选择Split Struct Pin

最后,像这样连接所有东西:

让我们回顾一下:

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

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

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

创建隧道生成器

转到 Content Browser 并确保您位于Blueprints文件夹中。创建一个以Actor作为父类的新蓝图类将其命名为BP_TunnelSpawner,然后打开它。

由于游戏会不断地生成隧道,因此最好创建一个生成函数。转到 My Blueprint 面板并创建一个名为SpawnTunnel的新函数。此功能的目的是在提供的位置生成隧道。

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

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

让我们继续创建一个输入参数。确保您位于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

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

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

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

创建生成点

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

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

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

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

在隧道中生成新的生产点

单击编译,然后切换到BP_TunnelSpawner

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

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

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

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

接下来,创建一个新函数并将其命名为SpawnTunnelAtSpawnPoint。创建以下图表:

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

为了让BP_TunnelBP_TunnelSpawner通信,它需要一个引用。如果没有通信,BP_TunnelSpawner将不知道何时生成下一个隧道。

创建对 Tunnel Spawner 的引用

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

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

单击编译,然后切换回BP_TunnelSpawner

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

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

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

编写触发区脚本

单击编译,然后切换到BP_Tunnel

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

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

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

左键单击并拖动Other Actor引脚。释放左键单击空白区域并从菜单中选择Cast to BP_Player

注意:由于隧道在另一条隧道的末端产生,它会触发该隧道的TriggerZone如果Other Actor是隧道,则强制转换为 BP_Player将阻止任何其他节点执行。

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

让我们一步一步来:

  1. 当一个Actor与TriggerZone重叠时,将执行On Component Begin Overlap (TriggerZone)节点
  2. Cast to BP_Player节点检查重叠的 Actor 是否是玩家
  3. 如果是玩家,那么BP_TunnelSpawner将生成一个新隧道。它的位置将位于最后生成的隧道的SpawnPoint组件。
  4. 由于旧隧道不再使用,游戏使用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节点的Input Object引脚。

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

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

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

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

产生后续隧道

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

这是最终的图表:

概括:

  1. ForLoop节点一共会执行3次
  2. 在第一个循环中,它将在玩家的位置生成一条隧道
  3. 在随后的循环中,它将在最新隧道的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设置为提供的网格。

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

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

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

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

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

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

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

随机化墙

您可以使用Range 节点中的 Random Integer来获取随机数。该节点将返回一个>= Min和 <= Max的值。

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

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

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

这将为WallMesh添加0到360度之间的随机旋转。

这是最终的图表:

概括:

  1. Select节点提供网格列表
  2. 使用Random Integer in Range节点选择随机网格
  3. Set Static Mesh节点将WallMesh设置为选定的网格
  4. AddLocalRotation节点向WallMesh添加随机旋转偏移

单击编译,然后关闭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 变量

单击编译,然后切换到BP_Tunnel。在 Components 面板中,右键单击WallMesh并选择Add Event\Add OnComponentHit。这会将以下节点添加到您的事件图表中:

每当另一个Actor与WallMesh碰撞时,该节点就会执行。

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

左键单击并拖动Other Actor引脚。释放左键单击空白区域并从菜单中选择Cast to BP_Player

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

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

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

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

显示重启按钮

您将显示的小部件名为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。完成后,创建以下图表:

概括:

  1. Add to Viewport将在屏幕上显示RestartWidget
  2. Set Input Mode UI Only 将限制玩家与 UI 的交互。这样玩家就不能在他们死的时候四处走动。
  3. 顾名思义,Set Show Mouse Cursor只是显示鼠标光标

要显示重启按钮,您只需在播放器与墙壁碰撞后调用DisplayRestart即可。

调用显示函数

关闭DisplayRestart图形,然后单击Compile

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

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

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

最后一步是当玩家点击按钮时重新开始游戏。

重启游戏

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

  1. 重置Player。这包括从屏幕上删除重新启动按钮。
  2. 重生隧道。这样玩家就从隧道的起点开始。

让我们从重置Player开始。

重置Player

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

概括:

  1. Set Is DeadIsDead设置为false。这重新启用了向前运动。
  2. Remove From Parent从屏幕上删除RestartWidget
  3. Set Input Mode Game Only重新启用游戏输入,以便玩家可以四处移动
  4. Set Show Mouse Cursor隐藏鼠标光标

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

重生隧道

单击编译,然后关闭BP_Player

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

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

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

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

接下来,创建以下节点:

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

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

这是最终的图表:

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

处理按钮点击

单击编译,然后关闭BP_TunnelSpawner

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

选择RestartButton,然后转到 Details 面板。转到事件部分,然后单击OnClicked旁边的按钮

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

重新创建以下内容:

概括:

  1. Get Owning Player Pawn返回玩家当前控制的 Pawn
  2. Cast to BP_Player检查 Pawn 是否属于BP_Player
  3. 如果是,它将调用RestartGame函数。此功能重置Player并隐藏重新启动按钮。
  4. Get All Actors of Class and Get返回BP_TunnelSpawner然后调用SpawnInitialTunnels。此功能将删除现有隧道并生成新隧道。
注意:您可能想知道为什么我使用Get All Actors Of Class而不是使用对BP_TunnelSpawner的引用。主要原因是因为BP_Tunnel与WBP_Restart没有关系。对于像这样的简单游戏,执行上述方法比找出存储引用的位置更容易。

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

猜你喜欢

转载自blog.csdn.net/qq_52825422/article/details/126652707