隧道
1.推动玩家前进
1.创建偏移量
- 在
BP_Player
蓝图中创建一个命名为ForwardSpeed
的变量,并将其初始值设置为2000 - 将
**Forward**
和**Delta Seconds**
相乘,获得与帧率无关的偏移量 -
2.沿单轴移动
要移动播放器,需要创建一个
**AddActorWorldffset**
节点,设置**Sweep**
为**True**
- 将
Float
结果与Delta Location
相连时,虚幻引擎会自动将其转换成Vector/向量
- Float 值会放入 Vector 的X、Y、Z分量中。因为此游戏中,前进运动只沿X轴移动,因此需要对其进行
**Split Struct Pin**
操作,此时**Delta Location**
引脚不能有连接。 回顾:
创建一个以
Actor
类为父类的蓝图,将其命名为**BP_TunnelSpawner**
创建一个函数以在提供的位置不断生成隧道,将其命名为
**SpawnTunnel**
1.创建
Spawn Tunnel
的Entry
节点:- 若要将位置传递给函数,该函数需要一个
**input parameter/输入参数**
,调用这个函数时,这些引脚将显示为输入引脚,该参数还将作为输入引脚在Spawn Tunel
函数的Entry
节点 - 创建
Spawn Tunnel
的Entry
节点并命名为**SpawnLocation**
,设置为Vector
类型 -
2.设置生成隧道及其生成位置:
添加
**Spawn Actor for class**
节点,并为其选择**BP_Tunnel**
类来生成隧道- 选择
**Spawn Transform**
引脚,对其进行**Split Struct Pin**
操作,并将其与**Entry**
节点进行链接。 - 完成该操作后,每次调用
**SpawnTunnel**
函数时,该函数将在提供的位置生成一个**BP_Tunnel**
实例
- 若要将位置传递给函数,该函数需要一个
测试隧道生成器
1.创建触发区域
- 在蓝图文件夹中打开
BP_Tunnel
,并添加Box Collision
组件并为其命名为**TriggerZone/触发区**
- 由于目前碰撞区域很小,因此选中
**TriggerZone**
组件,并将其**Shape**
—**Box Extent/盒体范围**
设置为(32, 500, 500) - 将位置属性设置为(2532, 0, 0),这会将
**TriggerZone**
放在隧道网格的末端。即:当玩家到达隧道尽头时,才会生成新的隧道。 -
2.创建生成点
要定义生成点的位置,可以使用
**Scene**
组件,因为这些组件只包含了转换,在视窗中也可见。- 向
BP_Tunnel
中的物体添加Scene
组件,并将其重命名为SpawnPoint
- 由于隧道网格在X轴上的长度为2500单位,因此连接点也应当在该处,将其位置属性设置为 (2500, 0, 0)
-
3.生成点的生成隧道
下一个
BP_Tunnel
应该在最远隧道的SpawnPoint
生成,这样隧道将始终继续。- 由于最远的隧道始终是最后生成的隧,因此对其获取引用即可。
- 通过下图操作创建变量,并将其重命名为
Newest Tunnel
,完成链接。此时将始终对最远的隧道进行引用 - 创建一个新函数,并将其命名为
**SpawnTunnelAtSpawnPoint**
,创建以下图形。该操作将获得最新的隧道及其**SpawnPoint**
组件的位置,然后由**Spawn Tunnel**
在此位置生成一个新的隧道。 为
BP_Tunnel
与BP_TunnelSpawner
进行通信,需要一个引用
4.创建对
Tunnel Spawner
的引用在
BP_Tunnel
,添加一个新变量,将其重命名为Tunnel Spawner
,将其变量类型设置为BP_TunnelSpawner
,并将其变量类型设置为BP_TunnelSpawn\对象引用
- 在
BP_TunnelSpawner
,打开Spawn Tunnel
的Graph并添加以下节点 -
5.编写触发区域脚本
在
BP_Tunnel
中添加OnComponentBeginOverlap
事件,当Other Actor
与TriggerZone
重叠时,此节点开始执行。
- 首先,需要检查穿过
**TriggerZone**
是否是玩家 - 拖动
Other Actor
引脚,选择Cast to BP_Player
:由于另一条隧道在另一条隧道末端生成,因此它将触发该隧道的TriggerZone
,如果Other Actor
是Tunnel,则强转化成BP_Player
将阻止任何其他节点执行。 -
4.生成更多隧道
1.创建一定数量隧道的函数
打开
**BP_TunnelSpawner**
并创建一个名为**SpawnInitialTunnels**
的新函数
要生成指定数量的隧道,可以使用Forloop
节点。此节点将执行连接的节点指定的次数,要使**ForLoop**
节点执行n次,**Last Index**
需要设置为n-1次。添加一个ForLoop
节点并将其连接到Entry
节点。
当游戏开始时,玩家应始终在隧道中启动,因此需要在玩家的位置生成第一条隧道。2.生成第一条隧道
要确定是否生成了第一条隧道,可以检查是否设置了
**Newest Tunnel**
。如果未设置,则表示尚未生成第一个隧道。这是因为**Newest Tunnel**
是在游戏生成隧道之后才设置的- 要执行此检查,请在
**ForLoop**
之后添加**IsValid**
节点,并获取对**Newest Tunnel**
的引用,将其连接到**Isvalid**
节点的输入对象节点 - 如果未设置
**Newest Tunnel**
,则执行Is not Valid
引脚,反之亦然,添加以下内容并完成链接。 -
3.生成后续隧道
添加一个
**Spawn Tunnel at Spawn Point**
节点,并将其连接到**Isvalid**
节点的**Is Valid**
引脚1.ForLoop 节点总共将执行三次 2.在第一个循环中,它将在玩家的位置生成一条隧道 3.在随后的循环中,它将在最新隧道的
Spawn Point
生成隧道在
Event Graph
并删除Spawn Point
节点,在Event BeginPlay
之后添加一个Spanw Initial Tunnel
节点。 完成操作。这样在游戏开始时,将会生成三个隧道
障碍
1.制造障碍
- 打开
**BP_Tunnel**
,在Components
面板添加一个Static Mesh
组件并将其命名为WallMesh
,并在Details
将其更改为SM_Hole_01
,位置更改为2470, 0, 0
- 添加一个新的Float变量并将其命名为
**RotateSpeed**
,默认值设为30
- 在
Event Graph
创建以下设置,使Wall Mesh
按提供的量进行旋转
1.创建墙变体
- 需求:无需为每个变体创建新的蓝图,完成对
WallMesh
的随机化 - 在
BP_Tunnel
中创建一个名为RandomizeWall
的新函数,并对其与**Set Static Mesh**
节点连接,该节点会将**WallMesh**
设置为提供的网格体 - 使用
**Select**
节点创建静态网格体列表 **Select**
节点允许设置选项列表,而**Index**
输入则确定**Select**
节点输出的选项-
2.随机化墙体
可以通过
**Random Integer in Range**
节点来获取随机数,此节点将返回一个值,该值的取值范围为(Min, Max),因此将其设置为(0, 3),这将为其提供 0, 1,2, 3这四个值。- 添加
Random Float in Range
和AddLocalRotation
节点,并拆分引脚,为WellMesh
添加 0和360之间的随机旋转
- 总结:
**Select**
节点提供网格列表- 使用
**Random Integer in Range**
节点选择随机网格 Set Static Mesh
节点将WallMesh
设置为所选网格体AddLocalRotation
节点向WallMesh
添加随机旋转偏移量
2.处理墙壁碰撞
如果启用或禁止向前移动,可以使用布尔变量,布尔变量只有真或假的状态。
- 在
**BP_Player**
中,创建名为**IsDead**
的布尔变量。在**Event Tick**
节点创建**Branch**
分支节点,获取对**Isdead**
的引用,并将其连接到**Branch**
节点的条件引脚 完成以上连接,每当
Isadead
设置为True
时,玩家停止前进。当玩家撞墙时设置Isdead
变量、1.设置 Isdead 变量
创建
**WallMesh**
的**On Component Hit**
事件,每当另一个**Actor**
与**WallMesh**
发生碰撞时,此节点执行。- 首先需要检查
**WallMesh**
碰撞的**Actor**
是否是玩家 - 拖动
**Other Actor**
节点,将其与**Cast To BP_Player**
相连 - 添加
**Set Isdead**
节点,并勾选复选框将**Isdead**
设置为True,与**Cast To BP_Player**
节点完成相连 -
2.显示重新启动按钮
显示的控件为
**WBP_Restart**
,可以在UI
文件夹中找到 要显示或隐藏控件,需要对其进行引用。打开
BP_Player
,并创建名为RestarWidget
类型的变量,将其变量类型更改为**WBP_Restart**
的**object Refence**
- 添加
Create Widget
并将类值设置为WBP_Restart
,添加Set Restart Widget
组件节点,完成以下连接。 - 当玩家生成时,将会创建
WBP_Restart
实例
- 创建
Display Restart
函数,并添加Add to Viewport
节点以显示Restart Widget
。 Set Input Mode UI Only
将限制玩家对UI的交互Set Show Mouse Cursor
将对鼠标进行控制:显示或隐藏- 要显示重新启动按钮,应当在播放器和墙壁碰撞后调用
DisplayRestart
切换到
BP_Tunnel
,将DisplayRestart
节点添加到On Component Hit(WallMesh)
节点链的末尾。此后发生碰撞时,将出现重新启动按钮。重新启动游戏
打开
BP_Player
,创建名为RestartGame
的函数。- 完成以下连接
Set Isdead
将Isdead
设置为False,这将重新启用向前移动Remove from Parent
从屏幕中删除Restart Widget
Set Input Mode Game Only
使游戏重新启用游戏输入,以便玩家可以四处走动Set Show Mouse Cursor
设置隐藏鼠标光标。
打开BP_TunnelSpawner
并确保位于SpawnlnitialTunnel
事件图中。
- 需要在产生新的隧道之前移除现有的隧道
- 在
Entry
节点后面添加一个Sequence
节点,并将Then 1
引脚连接到Forloop
节点 **Sequence/序列**
节点按顺序执行其输出- 创建以下节点:此设置将获取所有隧道并将其从游戏中移除
- 将
Sequence
节点的Then 0
引脚连接到Get All Actors Of Class
节点。这将确保在生成过程之前移除隧道。
1.处理按钮点击
- 打开
WBP_Restart
,在Eent Graph
中点击RestartButton
按钮,创建OnCliked
。当玩家单机OnCliked(RestartButton)
时,此节点开始执行 Get Owning Player Pawn
返回当前玩家控制的PawnCast To BP_Player
检查Pawn是否属于BP_Player
,如果是,它就会调用RestartGame
函数,这个函数将会重置玩家并隐藏重启按钮。Get All Actors Class
设置Actor Class
为BP_TunnelSpawn
,然后调用SpawnInitalTuneles
,这个函数将删除现有的隧道并产生新的隧道。Get(a copy)
补充
1.ForLoop
Forloop
是利用counter
所具备的计算循环次数功能来进行处理的ForLoop
节点需要对计数器的初始值、结束值、循环处理、下一步进行的处理等进行设置。ForLoop
节点的输入项:exec输入项
:用于连接执行顺序的顺序。First Index
:为Counter
设置的初始值。进入该节点后,计数器被设置为该First Index
的值Last Index
:计数器的结束值。计数器每循环一次就+1,当到达该Last Index
值后,执行完循环处理后,直接进入之后的处理中。
ForLoop
节点的输出项:变量可以
Details
界面修改参数信息,将变量数据修改成Int类型,并将变量更改为数组- 编译完成后,继续在
Details
面板中Default
处单击+
号为数组创建初始值 -
3.ForEachLoop节点
**ForEachLoop**
节点是用于处理数组的专用节点,其输入输出项也是结合数组由ForLoop演变而来ForEachLoop
节点的输入项:Exec
:处理执行处理的顺序Array
:连接要处理的数组
ForEachLoop
节点的输出项:Loop Body
:将循环处理的内容连接至此以创建处理Array Element
:在ForEachLoop
中将以顺序从数组中取出值,所取出的值将从此处获得Array Index
:可获得取出值的Index
编号Completed
:数组处理完后,用于连接至后续的处理