在本教程中,你将通过构建两个常见Gameplay对象来创建平台解谜游戏:
压力板开关。
一个会对玩家做出反应的物理立方体。
你将使用关卡设计和游戏机制(如时间、物理和伤害)来调整谜题的难度,并引入玩家行为的后果。
开始之前
本教程假定你已了解以下主题,这些主题在设计解谜冒险游戏的前几节中介绍过:
材质
蓝图
变量
蓝图接口
在编辑器中运行模式
你需要用到在创建钥匙中创建的下列资产。
M_BasicColor_Blue
一种Gameplay设计方法
无论哪种类型,引人入胜的Gameplay都会让玩家产生相应的感受;PvP的刺激感或农场模拟的舒适感。 这种情绪响应有助于提高玩家的参与度。 如果游戏没有吸引力,玩家玩下去的可能性就会降低,这可能会影响项目的成功。
作为游戏设计师,你的工作就是通过关卡设计和游戏机制来设计Gameplay。 你可以直观地设计关卡,但就本教程而言,我们将使用公式来可视化该过程。
关卡设计
通过关卡设计,你可以增加或降低任务的难度。 例如,在平台跳跃游戏中,跳上平台就是一项任务。 如果你在角色跳跃距离的上限处放置一个平台,就会增加到达该平台并完成任务的难度。
然而,如果没有失败的后果,即使是高难度的任务也可能会让玩家感到安全。
安全感在游戏教学阶段会很有用,因为玩家可以无后果地学习操作。
但是,一直让玩家有安全感可能会影响你的游戏。 例如,如果没有紧张感,Boss战斗可能会让人觉得乏味,导致玩家缺乏投入感。
为了让玩家感到紧张,你可以使用游戏机制伤害带来后果。
游戏机制
伤害在数字上表示玩家失去贵重资源的几率,例如:
装备
道具
关卡进度
可操作的角色或不可操作的伙伴。
任务的难度和后果的严重程度会影响玩家感受到的紧张程度:
任务难度过大、后果小或回报低可能让玩家产生挫败感。
执行任务时的紧张程度会影响玩家满足获胜条件时的满足感。 满足感,尤其是当满足感与奖励结合在一起时,会产生让玩家继续游玩的动力。
胜利条件是玩家成功完成任务所必须满足的条件。
创建开关
开关是一种Gameplay对象,当有东西与之交互时,会产生效果。
通过学习如何创建开关,你可以设计Gameplay功能,例如按按钮开门。 在本例中,你将使用开关更改与游戏内Actor碰撞时的颜色。
逻辑构建
当对象或玩家与开关重叠时,开关将激活。 在开始构建之前,让我们通过回答以下问题来简单了解支持此交互的逻辑:需要对谁进行什么操作,以及何时进行?
以下是开关逻辑的详情:
在运行时,开关关闭。
如果玩家踩到开关,开关就会打开。
如果玩家离开开关,则开关会关闭。
由于开关有两种状态(开和关),你可以使用材质可视化运行时的每种状态。 在测试期间,这将快速验证逻辑是否正常工作。
创建材质
对于开关的关闭状态,使用M_BasicColor_Blue,对于开启状态,则需要创建自发光材质。
自发光材质会发光。
要创建自发光材质,请按照以下步骤操作:
在内容浏览器中,找到AdventureGame > Designer > Materials,右键点击并选择材质(Material)。
将新材质命名为
M_EmissiveColor,然后双击它以打开材质编辑器。在材质图表中,右键点击并搜索向量参数(Vector Parameter)。 点击它以将其填充到图表中,并将其命名为
Color。 此功能按钮材质光源的颜色。在Color节点上,双击色条以打开取色器。
选择你自己的颜色,或将其设置为十六进制sRGB
27F774FF以按照说明操作。右键点击并搜索另外两个节点:Constant节点和Multiply节点。
将Color节点连接到Multiply节点的A引脚。 然后,将C常量连接到Multiply节点的B引脚。 最后,将Multiply节点连接到M_EmissiveColor节点的自发光颜色(Emissive Color)引脚。
Constant的值(Value)可以控制材质的自发光强度或亮度。 你可以根据需要调整它,或将其设置为
25以遵循教程。点击保存后关闭材质。
你的Materials文件夹现在应如下所示:
由于M_EmissiveColor是本教程中唯一的自发光材质,因此你不需要创建任何实例。 不过,材质实例仍然是保持项目模块化并在开发环境中高效运行的绝佳方法。
接下来,你将构建开关。
设置蓝图类
开关将是一个包含静态网格体和盒体碰撞的蓝图。 盒体碰撞将检测与玩家的接触,从而触发开关的开启和关闭状态。
碰撞是指在运行时检测两个对象是否接触。 盒体碰撞以及球体和胶囊体碰撞是用于实现这些检测的几种常用体积。 例如,命中盒体就是使用碰撞形态来检测攻击成功的示例。
首先,请执行以下步骤:
在内容浏览器的AdventureGame > Designer > Blueprints中,新建一个名为
Activation的文件夹。在Activation内部,右键单击以创建一个新的蓝图类。
在选取父类(Pick Parent Class)对话框中,选择Actor。
将新蓝图命名为
BP_Switch,然后双击它,从而在蓝图编辑器中打开BP_Switch。在组件(Components)选项卡中,单击添加(Add)来创建静态网格体,搜索并选择
立方体(cube)。将立方体命名为
Switch。在细节面板的变换下,将Switch的缩放调整为
2.0、2.0、0.1。在组件(Components)选项卡中,点击添加(Add)并搜索
盒体碰撞(boxcollision),创建盒体碰撞。将其命名为
Trigger。在细节面板的位置中,将盒体碰撞的Z值调整为
200。在"缩放(Scale)"下,将其缩放调整为
1.5、1.5、5.0。 此盒体碰撞比静态网格体更厚,可轻松捕获碰撞。保存并编译蓝图。
你的蓝图文件夹现在应如下所示:
为避免在编译失败时丢失工作成果,请在进行重大更改后保存并编译蓝图。
接下来,你将创建变量来控制开关的行为。
创建变量
通过变量BP_Switch可以引用你刚刚创建的材质。 你不必将特定材质硬编码到开关中,而是可以动态替换材质,本教程稍后将执行此操作。
现在,在BP_Switch中创建以下变量:
变量名称 | 类型 | 默认值 | 说明 |
OnMaterial | 材质接口 |
| 打开时开关的颜色。 |
OffMaterial | 材质接口 |
| 关闭时开关的颜色。 |
在我的蓝图(MyBlueprint)选项卡的变量(VARIABLES)中,通过单击+按钮两次来创建两个新变量
将一个命名为
OnMaterial,另一个命名为OffMaterial。将其引脚类型设置为材质接口(对象引用)[Material Interface(Object Reference)]。
选择OnMaterial。 在细节面板中,找到类别(Category),创建一个名为
Setup的新类别。点击编译,获取其默认值(Default Value)。 在默认值下,选择
M_EmissiveColor。 至此变量设置完毕。选择OffMaterial。 在细节面板中,将其添加到Setup类别。
在默认值下,选择
M_BasicColor_Blue。保存并编译。
现在蓝图可以引用材质,你将使用逻辑指示开关何时使用它们。
实现你的逻辑
你应该有一个盒体碰撞、一个静态网格体和两个材质。 现在开关的逻辑可写为:
在运行时,Switch应该显示OffMaterial。
如果触发器检测到碰撞,则将Switch的材质设置为OnMaterial。
如果触发器停止检测碰撞,则将Switch的材质设置为OffMaterial。
要构建此逻辑,你将使用构造脚本指示BP_Switch在运行时使用OffMaterial:
在构造脚本(Construction Script)选项卡中,拖出构造脚本节点上的执行引脚,并搜索设置材质 (Switch)[Set Material (Switch)]。 点击以创建它。
在Set Material节点上,拖出Material引脚并搜索Get OffMaterial。 选择它。
保存并编译。
你将在事件图表(EventGraph)中处理其余逻辑。 要指示开关在重叠时打开和关闭,请执行以下步骤:
在事件图表中,删除Event BeginPlay、Event ActorBeginOverlap和Event Tick节点。 现在不需要它们了。
在我的蓝图(My Blueprint)选项卡中,在组件(Components)标题下,右键单击触发器(Trigger)并选择添加事件(Add Event)> 添加OnComponentBeginOverlap。
重复此过程以添加OnComponentEndOverlap节点。
从OnComponentBeginOverlap(Trigger)节点的执行引脚,拖出引线并搜索SetMaterial (Switch)。
从Set Material节点的Material引脚拖出一根引线,然后搜索Get OnMaterial。
从OnComponentEndOverlap(Trigger)节点的执行引脚拖出引线并搜索设置材质(switch)[Set Material (Switch)]。
从SetMaterial节点的Material引脚拖出一根引线,然后搜索Get OffMaterial。
开关已经暂时完成了,请保存并编译。
你的构造脚本图表现在应该如下图所示:
你的事件图表现在应该如下所示:
现在你可以测试项目,看看开关是否能正常工作。
将BP_Switch的实例从内容浏览器拖入Room 1。 点击播放模式(Playmode)工具栏中的三点菜单,然后选择当前摄像机位置(Current Camera Location)。 这样可以确保你从视口中的当前位置进入PIE模式,而不是跑遍整个关卡来测试单一功能。
在PIE模式下,当你踩到开关时,它应该会亮起。 当你离开时,它应该会变回蓝色。
模块化开发的好处
假设你需要两个开关而不是一个,但你希望第二个开关光源是红色而不是绿色。 你可以使用相同的逻辑构建一个新的开关,并分配红色材质,但这会耗费你的开发时间,并为你的项目带来更多开销。
开销是指资源的支出(处理能力、时间、存储量等)。
由于平台(计算机和游戏主机)的处理能力有限,游戏开发人员通常希望以模块化方式工作,以减少开销。
因为你已经使用了蓝图和变量来构建开关,所以你已经使用模块化工作方式。 让我们看看实际操作:
在蓝图编辑器中打开
BP_Switch,只需要在内容浏览器中双击它。在变量(Variables)下,选择OnMaterial并点击眼睛图标,将其打开。
选择OffMaterial,这次我们要用不同的方法做同样的事情;在细节面板中启用可编辑实例(Instance Editable)。 你会注意到眼睛图标睁开了;它现在是公共变量。
保存、编译并关闭。
关卡中应该已经有一个BP_Switch实例,现在拖入第二个实例。 在视口中选择任一开关后,细节面板将显示一个名为Setup的新UI类别。 这是你在创建变量中创建的变量类别。 Setup将公共变量显示为参数,你可以从视口动态更改这些参数。
尝试将材质更改为你想要的任何内容,并测试开关在PIE模式下的反应。 你会看到开关的每个实例都可以保存唯一的开和关材质,而无需从头创建新开关,从而加快开发并减少开销。
如果你希望自己的视口看起来和我们的完全一样,请在继续学习本教程之前删除第二个开关实例。
创建单个和多个激活
你的开关目前会无限次打开和关闭。 在某些情况下,我们会希望只激活一次。 例如,在通向战利品的走廊中,你可能需要一个开关来激活玩家必须避开的陷阱。 如果玩家成功避开陷阱并收集了战利品,开关不应再次激活陷阱。
你不必丢弃已构建的内容,而是添加一个布尔值,让开关仅使用一次。
变量名称 | 类型 | 默认值 | 说明 |
ActivateOnce | 布尔(Boolean) | False | 此开关是可以重复激活还是仅激活一次。 |
为此,请按照下列步骤操作:
在
BP_Switch的蓝图编辑器中,点击变量(Variables)下的+按钮添加新变量。将其命名为
ActivateOnce并将引脚类型设置为布尔(Boolean)。在细节面板中,勾选可编辑实例(Instance Editable)选框。
点击类别(Category)旁边的下拉菜单,然后选择Setup。
点击编译以访问变量的默认值并验证它是否已取消选中。 这意味着此蓝图不会默认启用ActivateOnce。
在事件图表中,右键点击并搜索Branch节点。
从Branch节点的Condition引脚中拖出并搜索Get ActivateOnce。
将On Component End Overlap (Trigger)节点的执行引脚拖到Branch节点的执行引脚。 它应该会断开与SetMaterial节点的连接。
将Branch节点的False引脚连接到Set Material节点的执行引脚。 这意味着当对象离开开关时,系统会做出决定:如果ActivateOnce切换为True,则开关停止检测碰撞。 如果ActivateOnce切换为False,则开关将无限期有效。
保存、编译并关闭蓝图。
在视口中选择
BP_Switch。 在细节面板中,ActivateOnce应该是该实例的可切换复选框。 启用它以了解其工作原理。
你的事件图表现在应该如下所示:
点击运行,在PIE模式下测试你的变量。 启用ActivateOnce后,即使在离开开关后,开关也应该保持亮起。
使用物理效果激活开关
在本教程的后半部分,玩家将需要在完成关卡其余部分的同时保持按住开关。 为此,你将创建此谜题的第二个Gameplay对象——物理立方体。 这会将游戏机制、物理系统融合到你设计的谜题中。
要使用蓝图创建物理立方体,请按以下步骤操作:
在内容浏览器中,找到AdventureGame > Designer > Blueprints > Activation,单击右键并创建新的蓝图类。
在选取父类(Pick Parent Class)对话框中,选择Actor。
将新蓝图命名为
BP_Cube。双击它以在蓝图编辑器中打开
BP_Cube。在组件(Components)选项卡中,单击添加(Add)来创建静态网格体,搜索并选择
立方体(cube)。将网格体命名为
Cube。在细节面板的静态网格体下,搜索并选择SM_ChamferCube。
将Z位置设置为
50.0。在材质(Materials)下,将元素0(Element 0)设置为
M_BasicColor_Blue。在物理(Physics)下,启用模拟物理(Simulate Physics)。 此设置会启用UE的Chaos物理系统引擎,让立方体对玩家的推动做出反应。
保存并编译。
要测试功能,请将BP_Cube实例拖入关卡中的开关附近。 按下运行进入PIE模式,并使用WASD字母键将BP_Cube推到开关上以将其打开。
调试
如果你将立方体推到开关上,它会打开,但你可能会注意到一个问题。 如果你走出开关,即使立方体仍与开关重叠,开关也会关闭。
查看当前逻辑以查找错误:
如果触发器停止检测碰撞,则将Switch的材质设置为OffMaterial。
要解决此问题,指示触发器在继续之前检查是否有重叠的Actor:
如果触发器停止检测到碰撞,并且没有Actor与其重叠,则将Switch的材质设置为OffMaterial。
要对蓝图进行调整,请按照以下步骤操作:
在
BP_Switch的蓝图编辑器中,右键点击并创建Branch节点。从Condition引脚拖出,搜索并创建一个Is Empty(数组)节点。
从Is Empty节点的目标数组(Target Array)引脚搜索并创建获取重叠Actor(Trigger)[Get Overlapping Actors (Trigger)]。
将类筛选器设置为Actor。
要将此逻辑连接到现有节点,则从第一个Branch节点的False引脚拖出,并将其连接到第二个Branch节点的执行引脚。
将第二个Branch节点上的True引脚连接到Set Material节点的执行引脚。
保存并编译。
你的事件图表现在应该如下所示:
要调整触发器的碰撞设置,请执行以下步骤:
在组件(Components)选项卡中,选择触发器(Trigger)。
在细节面板的碰撞预设(Collision Presets)标题栏下,将下拉菜单设为自定义(Custom)。
在碰撞已启用(Collision Enabled)下拉菜单中,选择已启用碰撞(查询和物理)[Collision Enabled (Query and Physics)]。
在对象类型(Object Type)下拉菜单中,选择WorldDynamic。
在WorldDynamic旁边,勾选忽略(Ignore)。
保存并编译。
进入PIE模式以测试你的解决方案。 只要有Actor与之重叠,开关就应该保持亮起,无论Actor是否移开。
创建其他功能
到目前为止,你已经创建了一个能够打开和关闭的开关。 这样可以可视化表示开关是否正常运行,不过它的用处还有很多。 接下来,你将使用该开关激活关卡中的其他对象。
首先,你将创建一个包含两个函数的蓝图接口;每个都代表开关的开启和关闭状态。 这些函数的用法类似于对象之间发出的事件。
在内容浏览器中,找到AdventureGame > Designer > Blueprints > Core,单击右键并找到蓝图。 然后,选择蓝图接口(Blueprint Interface)。
将接口命名为
BPI_Interaction。 双击打开蓝图接口窗口。在我的蓝图(MyBlueprint)面板中,应该已经存在一个新的函数。 将其命名为
fnBPISwitchOn。单击添加(Add),然后单击函数以创建第二个函数。 将其命名为
fnBPISwitchOff。这样接口就完成了。 保存、编译并关闭。
接下来,你要创建一个数组(Array),其中包含你希望开关激活的所有对象。 在本教程中,我们会使用数组来管理开关激活哪些对象,而不是为每个新对象创建唯一的逻辑。
变量名称 | 类型 | 默认值 | 说明 |
InteractObjectList | Actor数组 | 无(None) | 此开关激活的Actor数组。 |
在
BP_Switch的我的蓝图(My Blueprint)选项卡的变量(VARIABLES)下,单击+按钮以创建新变量。将其命名为
InteractObjectList并将引脚类型设置为Actor(对象引用)[Actor (Object Reference)]。在细节面板中的变量类型(Variable Type)旁边,将容器类型设置为数组(Array)。
要使其成为UI参数,请选中可编辑实例(Instance Editable)并将其添加到Setup类别。
保存并编译。
我们要使用逻辑来指示开关迭代数组(当前为空)中的每个对象,并使用之前创建的BPI_Interaction接口向其发送信号。 这里我们要使用For Each Loop。
为此,请按照下列步骤操作:
在事件图表中,从Set Material节点(在On Component Begin Overlap节点上)的执行引脚拖出,然后搜索For Each Loop。
要指示要为哪些对象执行该事件,请拖出For Each Loop上的Array引脚,然后搜索Get InteractObjectList。
最后,拖出For Each Loop上的Loop Body引脚,并搜索fnBPISwitchOn。 这就是你要调用的事件。
将For Each Loop上的Array Element引脚连接到fnBPISwitchOn节点上的Target引脚。
必须为On Component End Overlap(Trigger)执行相同的操作。 要加快该过程,请选择For Each Loop和Interact Object List节点,并使用右键单击 > 复制或按Ctrl+C进行复制。 按Ctrl+P将其粘贴到图表中。
将Set Material节点的执行引脚连接到For Each Loop的执行引脚。
从For Each Loop的Loop Body引脚拖出并搜索fnBPISwitchOff。 将Array Element引脚连接到Target引脚。
你的开关暂时完成了。 保存、编译并关闭。
你的事件图表现在应该如下所示:
现在你已经打好了基础,可以为关卡中的每个开关实例激活唯一的对象列表。 在下一节教程中,你将创建此挑战的第三个Gameplay对象——移动平台。