在本教程系列中,你使用关卡设计和游戏机制为玩家设计Gameplay。 你构建的谜题、钥匙和门都是Gameplay循环的组成部分。
Gameplay循环是玩家重复的一系列操作,构成Gameplay的核心。
你仍然需要为构建的关卡完成循环。 在本教程中,你将构建一个获胜界面,告知玩家他们已经完成了当前关卡。 你还将构建一个关卡过渡点,用于验证获胜条件并将玩家带到下一个关卡。
关卡完成后,你将在本轨道所学内容的基础上探索各种方法进行扩展。
获胜条件是玩家为完成Gameplay任务、关卡或游戏而必须满足的目标。 你的游戏循环必须提供满足获胜条件的方法。 在非线性游戏中,获胜条件可能不止一个。
开始之前
本教程假定你已了解以下主题,这些主题在《设计解谜冒险游戏》的前几节中介绍过:
控件蓝图
蓝图
变量
碰撞体积
在编辑器中播放模式
父节点资产和子节点资产
你需要准备好在陷阱和伤害中创建的下列资产:
WBP_EliminationScreen控件蓝图BP_Key蓝图类Enum_KeyType枚举
构建关卡结束
即使你已经完成了关卡核心Gameplay的构建,也能够制作一段过渡点,让玩家以一种有趣的方式完成关卡。 在本例中,你将构建一个跳跃板,将玩家弹到一个升起的平台。 稍后,你将在平台上放置关卡过渡点。
构建平台
要在其中一个房间中构建高架平台,请使用 LevelPrototyping > Meshes文件夹中的SM_Cube和SM_Cylinder静态网格体。
教程示例关卡使用一个3.5平方米的四根柱子平台,如下所示:
如果想将这些粗模复制到你的关卡中,请复制下方的代码片段。 如果你按照示例关卡的步骤操作,这些形状将出现在Room 3的后角附近。 你可以根据需要移动它们。
要复制平台,请执行以下步骤:
点击复制完整代码片段(Copy Full Snippet)。
Command LineBegin Map Begin Level Begin Actor Class=/Script/Engine.StaticMeshActor Name=StaticMeshActor_785 Archetype="/Script/Engine.StaticMeshActor'/Script/Engine.Default__StaticMeshActor'" ExportPath="/Script/Engine.StaticMeshActor'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.StaticMeshActor_785'" Begin Object Class=/Script/Engine.StaticMeshComponent Name="StaticMeshComponent0" Archetype="/Script/Engine.StaticMeshComponent'/Script/Engine.Default__StaticMeshActor:StaticMeshComponent0'" ExportPath="/Script/Engine.StaticMeshComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.StaticMeshActor_785.StaticMeshComponent0'" End Object Begin Object Name="StaticMeshComponent0" ExportPath="/Script/Engine.StaticMeshComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.StaticMeshActor_785.StaticMeshComponent0'" StaticMesh="/Script/Engine.StaticMesh'/Game/LevelPrototyping/Meshes/SM_Cylinder.SM_Cylinder'" StaticMeshImportVersion=1 bUseDefaultCollision=False StaticMeshDerivedDataKey="STATICMESH_FD1BFC73B5510AD60DFC65F62C1E933E_228332BAE0224DD294E232B87D83948FQuadricMeshReduction_V2$2e1_6D3AF6A2$2d5FD0$2d469B$2dB0D8$2dB6D9979EE5D2_CONSTRAINED0_100100000000000000000000000100000000000080FFFFFFFFFFFFFFFFFFFFFFFF000000000000803F00000000000000803F0000803F00000000000000003D19FC1626C9B2485E57DB4B8EC731318B8215AE8D46FAD400000000010000000100000000000000010000000100000000000000000000000100000001000000400000000000000001000000000000000000F03F000000000000F03F000000000000F03F0000803F00000000050000004E6F6E65000C00000030000000803FFFFFFFFF0000803FFFFFFFFF0000000000000041000000000000A0420303030000000000000000_RT00_0"在虚幻编辑器中,确保视口或大纲视图为活动面板,然后按Ctrl + V。
接下来,你将添加一个跳跃板,用于将玩家弹到平台上。
使用跳跃板
虽然你可以从头开始编译跳跃板,但这会浪费你的时间。 在时间有限的开发环境中,导入预制(prefab)资产比创建自己的资产会很有用。 选择符合游戏视觉效果样式的预制件可以加快开发速度,同时又不会显得过于突出。
在本教程中,你将使用第一人称模板随附的资产BP_JumpPad。
要集成BP_JumpPad,请执行以下步骤:
在内容浏览器中,找到LevelPrototyping > Interactable > JumpPad。
将
BP_JumpPad的实例拖到关卡中,位于平台前面。 如果你想匹配本教程中显示的确切位置,请将BP_JumpPad的位置设置为1790,-1460,10。
现在,你的关卡应与下图类似:
现在可以测试你的成果了。 首先,确保所有BP_Enemy的最大速度为0。 这可确保你在测试时不会遇到移动的敌人。
在视口中右键点击并选择从这里运行(Play From Here),从你的当前位置对你的关卡进行试玩。 走上跳跃板并尝试到达平台。
请注意,即使使用跳跃台的推进,你的玩家角色也无法到达平台。 你可以通过调整跳跃板的速度参数来解决这个问题。
与你在蓝图中创建的许多可编辑变量一样,速度参数是跳跃板资产的预制、实例可编辑变量。
要调整速度,请执行以下步骤:
在视口中选择
BP_JumpPad。在细节面板中,将速度(Velocity)(Z)设置为
1000。
现在再次测试你的关卡。 你应该能够跳到平台上。
接下来,你将创建在玩家完成关卡时显示的获胜界面
创建获胜界面
你将使用控件蓝图创建获胜界面,类似于你在陷阱和伤害中创建的WBP_EliminationScreen游戏结束界面。 由于这两个界面非常相似,你将使用WBP_EliminationScreen作为起点。
要通过复制游戏结束界面来创建获胜界面,请执行以下步骤:
在内容浏览器中,导航到AdventureGame > Designer > Blueprints > Widgets。
右键点击
WBP_EliminatedScreen并点击复制(Duplicate)。将新控件蓝图命名为
WBP_WinScreen,然后双击它在控件编辑器中打开。 你的Widgets 文件夹现在应如下所示:要更改消息,请点击层级中的文本控件。
在细节面板的内容(Content)标题下,在文本(Text)旁边的文本框内输入
Level Complete! …Loading the Next Level。在Appearance标题下,点击颜色(Color)和不透明度(Opacity)旁边的色条打开取色器。 选择你喜欢的颜色,或将十六进制sRGB值设置为
FFE000FF以执行后续操作。获胜界面的文本较短,因此你可以增加其大小以更好地填充屏幕。 在"字体(Font)"标题下,将"大小(Size)"更改为
72或你认为最易辨认的大小。保存、编译并关闭控件编辑器。
接下来,你将创建关卡过渡点。
创建关卡过渡
关卡过渡会加载下一个关卡。 你可以通过多种方式触发关卡过渡;当玩家完成过场动画、拾取物品或到达关卡终点时。
在本教程中,关卡过渡将是在以下两种情况发生时触发的蓝图:
玩家与关卡过渡重叠。
满足获胜条件。
要创建新的蓝图,请按以下步骤操作:
在内容浏览器中,导航到AdventureGame > Designer > Blueprints。
右键点击并选择新建文件夹。 将该文件夹命名为
LevelTransition。在Level Transition文件夹中,右键点击并选择"蓝图类(Blueprint Class)"以创建新蓝图。
在“选取父类”(Pick Parent Class)窗口中,选择Actor。
将此新蓝图命名为
BP_LevelTransition,然后双击以在蓝图编辑器中将其打开。
你的关卡过渡文件夹现在应如下所示:
与你目前创建的其他蓝图类似,关卡过渡需要满足以下条件:
玩家在运行时可以看到的静态网格体。
玩家与之碰撞时要检测的碰撞形状。
支持交互的逻辑。
让我们先构建网格体和盒体碰撞,然后再讨论逻辑。
要创建静态网格体和碰撞形状,请按照以下步骤操作:
在
BP_LevelTransition的组件(Components)选项卡中,点击添加(Add)按钮并搜索cube创建新的静态网格体。将此静态网格体命名为
TransitionPoint。选择TransitionPoint后,在细节面板中,将其缩放设置为
3.0,3.0,0.1。 它的大小适合示例关卡的末端平台;你可以调整大小,使其达到最适合关卡的效果。回到组件选项卡,选择DefaultSceneRoot。 点击添加(Add)按钮,然后搜索
box collision创建碰撞形状。将盒体碰撞命名为
LevelTrigger。选择LevelTrigger后,在细节面板中将其缩放设置为
4.0、4.0、2.0。 将其Z位置设置为55.0。如果盒体碰撞未显示为正确的形状,请确保它不是TransitionPoint的子节点。
保存并编译。
使用逻辑构建
BP_LevelTransition应该按顺序执行五个操作:
检查是否存在重叠。
验证获胜条件。
禁用玩家输入。
显示获胜界面。
加载下一关。
让我们逐步创建支持这些交互的逻辑。
检查重叠
要构建检查重叠的逻辑,请按照以下步骤操作:
在
BP_LevelTransition的我的蓝图(MyBlueprint)选项卡的变量(Variables)分段中,单击+按钮以创建新变量,并将其命名为OtherActor。将引脚类型设置为Actor(Object Reference)。
在事件图表中,删除三个现有事件节点。 现在不需要它们。
在组件选项卡中,右键点击LevelTrigger,然后点击添加事件 > 添加OnComponentBeginOverlap。 此函数检查对象何时与碰撞形态重叠。
从Exec引脚拖出并创建Set Other Actor。
连接两个Set Other Actor引脚。
接下来,你将构建用于验证获胜条件的逻辑。
验证获胜条件
在本教程中,获胜条件将是收集所有三把钥匙。 选择此特定条件的原因是预测并防止破坏游戏规则的玩家操作。
例如,如果获胜条件是"玩家与关卡过渡重叠",并且玩家想方设法越过房间墙壁,他们就可以绕过整个关卡。 通过使用钥匙作为获胜条件,玩家必须完成游戏循环,即使他们想方设法越过墙壁和门。
虽然我们无法预测每一个漏洞,但预防性设计可以防止玩家破坏游戏。
要创建用于存储钥匙数据的数组,请执行以下步骤:
在
BP_LevelTransition的我的蓝图(MyBlueprint)选项卡中,单击+按钮以创建新变量,并将其命名为HeldKeys。将引脚类型设置为Enum Key Type,将容器类型设置为Array。
从Set节点的Exec引脚拖出并创建fnBPIGetKeys。
从Target引脚拖出并创建Get Other Actor。
从fnBPIGetKeys上的Exec引脚拖出引线并创建Set Held Keys。
连接两个Held Keys数组引脚。
要创建用于设置获胜条件的枚举键类型,请按照以下步骤操作:
创建新的变量,然后将其命名为
RequiredKeys。 这是你的获胜条件。确保引脚类型为Enum Key Type,容器类型为Array。
在细节面板中,启用实例可编辑(Instance Editable)并将类别设置为
Setup。编译蓝图以访问默认值。 点击 + 按钮,将三个新元素添加到数组。
点击索引下拉菜单并将索引设置为黄色、蓝色和红色。
你将创建一个布尔值来验证是否满足条件。 For Each Loop with Break循环将循环遍历HeldKeys数组以检查每每把钥匙,如果缺少钥匙就会中断。
要构建检查缺失钥匙的逻辑,请按照以下步骤操作:
创建新的变量,然后将其命名为
FoundAllKeys。将引脚类型设置为Boolean,将容器类型设置为Single。
从SetHeldKeys的Exec引脚拖出并创建带For Each Loop with Break。
从For Each Loop的Array引脚拖出引线并创建Get Required Keys节点。
从循环的Loop Body引脚拖出引线并创建Branch。
从Condition引脚拖出引线并创建Contains Item (Array)节点。
从Contains节点的Target Array引脚拖出引线并创建Get Held Keys。
将Condition节点上的Item to Find引脚连接到循环节点上的Array Element引脚。
从Branch节点的True引脚拖出,然后创建Set Found All Keys。 点击FoundAllKeys旁的复选框,将其设置为 true。
从Branch节点的False引脚拖出,并创建Set Found All Keys。 将复选框留空,将Exec引脚连接到or Each Loop上的Break引脚。
在我们之前查看的序列中,你还有三个步骤需要执行,但前提是玩家拥有所有钥匙:
禁用玩家输入。
显示获胜界面。
加载下一关。
要使用FoundAllKeys结果启动逻辑序列,请执行以下步骤:
从For Each Loop的Completed引脚拖出引线并创建Branch。
从Condition引脚拖出引线并创建Get FoundAllKeys。
从Branch节点的True引脚拖出,创建一个Sequence节点。
由于你需要按此序列编译三个操作,请点击添加引脚(Add Pin)按钮。
让我们进入序列中的下一个步骤:禁用玩家输入。
禁用玩家输入
在显示获胜界面时,禁用玩家输入可以防止玩家四处移动并受到意外伤害。
要禁用玩家输入,请执行以下步骤:
从Sequence的Then 0引脚拖出引线并创建Disable Input节点。
从Disable Input节点的Target引脚,创建Get Other Actor。
从Player Controller引脚拖出并创建Get Player Controller节点。
接下来,你需要构建显示获胜界面的逻辑。
显示获胜界面
要显示你的WBP_Winscreen控件,请执行以下步骤:
从Sequence节点的Then 1引脚拖出引线并创建Create Widget节点。
将类(Class)设置为WBP_WinScreen。
从创建控件Create Widget节点上的Exec节点拖出引线并创建Add to Viewport节点。
将Create Widget上的Return Value引脚连接到添加到视口Add to Viewport上的Target节点。
你觉得这个逻辑有问题吗? 现在,你可以先不解决问题,继续构建最后的步骤。 稍后,你将测试关卡以发现问题并构建解决方案。
加载下一个关卡
在本教程中,你将使用当前关卡作为下一个关卡的占位符。 当你设计自己的游戏时,过渡点应该将玩家带到一个全新的关卡。
要构建用于加载当前关卡的逻辑,请执行以下步骤:
从Sequence节点的Then 2引脚拖出引线并创建一个Open Level (by Object Reference)节点。
从Open Level的Level引脚拖出并搜索Promote to Variable。 这将强制创建World类型变量。
你也可以通过我的蓝图(MyBlueprints)选项卡创建此变量,但世界(World)引脚类型可能很难找到。
选择World变量后,在细节面板中,将变量重命名为
NextLevel。将其添加到Setup类别,并启用实例可编辑(Instance Editable)。
编译蓝图以访问变量的默认值,并将其设置为要加载的关卡。 如果你按照本教程操作,请将其设置为
Lvl_Adventure以循环当前关卡。保存并编译。
现在可以测试你的成果了。 将BP_LevelTransition的实例拖动到升高的平台上。然后,你可以获取钥匙来满足获胜条件。 为此,你可以将在创建钥匙中创建的黄色、蓝色和红色钥匙的实例,并放置到同一个空间中。
你的关卡现在看起来应该像这样:
在视口中右键点击并选择从这里运行(Play From Here),从你的当前位置对你的关卡进行试玩。 如果你跳到平台上并激活关卡过渡,你会注意到屏幕定住,下一个关卡直接开启,玩家并没有时间阅读获胜界面的消息。
你将在下一小节中解决此问题。
创建延迟
本教程使用打开关卡来关闭当前关卡,并将下一个关卡作为新的游戏实例打开。 加载期间,Open Level会将游戏定住。 根据玩家的反应,如果定住的时间太短就无法读取获胜屏幕,而太长看起来像是游戏崩溃了。
许多游戏,甚至是那些使用关卡流送的游戏,都会利用加载屏幕来让玩家知道游戏正在正常运行,他们应该等待。 加载界面还解决了另一个问题;漫长、频繁或枯燥的等待时间可能会破坏沉浸感并导致沮丧。 加载屏幕通常包括提示、动画或音频,以便在游戏未运行时吸引玩家的注意力。
要通过设计解决此技术问题,你需要创建有意的延迟,以实现以下目标:
使所有玩家的加载时间相等。
确保玩家有足够的时间阅读获胜界面。
为玩家提供可查看的内容,从而掩盖加载时间。
要插入延迟,请按照以下步骤操作:
打开
BP_LevelTransition。 在我的蓝图(MyBlueprint)选项卡中,单击+以添加新变量,并将其命名为LevelLoadDelay。将引脚类型设置为浮点。
在细节面板中,启用实例可编辑(Instance Editable)并将类别设置为Setup。
编译蓝图,以便访问默认值。 关卡加载延迟(Level Load Delay)将设置你希望延迟持续的时间长度。 i可以和我们一样设为
5.0秒。在事件图表中,导航到Sequence节点。 要插入延迟,从Then 2引脚拖出引线并创建Delay节点。
从Duration引脚拖出引线并创建Get LevelLoadDelay。
保存、编译并关闭蓝图。
最终的BP_LevelTransition事件图表应如下所示:
现在再次测试你的关卡。 当你重叠关卡过渡点时,应该会显示获胜界面,背景应该变得模糊,并且玩家输入应该会被禁用五秒钟,然后你的玩家角色会出现在下一关卡中。
最后一次对关卡进行游戏测试前,请记得将键从Room 3移除,并将BP_Enemy的最大速度(Max Speed)改回200。
从概念到创作
我们来看看项目设置与关卡粗模搭建与我们的最终关卡的对比。 从最初的设计,我们的关卡设计和Gameplay循环发生了变化,旨在解决错误,创建新功能,或解决游戏测试人员在开发过程中发现的限制。
通过规划关卡、采用模块化工作方式、解决设计方面的技术问题以及使资产井井有条,你就可以在游戏开发过程中遇到各种局限或新功能发生变化时依然保持灵活性。
完成这一段之后,你就完成了一个可玩的演示关卡。 现在你有了构建块来设计多个关卡。 你可以无限制地组合开关、陷阱、钥匙、门和敌人,按照自己的样式设计新的Gameplay循环。 连接在一起后,每个关卡能组合成一个更大项目,变成一个完整的游戏。
示例项目
点击下方链接,可下载通过本系列文档教程所构建的最终项目。 你可以使用此示例项目预览最终成品,也可以将其作为参考,了解我们是如何构建和设计该项目的。
(下载大小:75 MB)
要打开项目,请先解压文件,然后将adventuredesigner文件夹移动到你的虚幻项目目录下(默认位置为:C:\Users\UserName\Documents\Unreal Projects)。
下一步
如果你想继续完善关卡,添加材质、灯光、后期处理效果、音效和视觉特效,可以尝试Artist Track教程系列。
如果你想继续学习构建另一个蓝图,请前往Designer Track教程系列的附加模块。
如果你有兴趣将项目打包为独立程序以进行测试和共享,请参阅以下文档: