Choose your operating system:
Windows
macOS
Linux
在此 蓝图通信项目 中,我们将创建一个简单的射击场游戏。在项目的进程中,您将学习到如何将信息从关卡传输到一个角色,以及如何将角色信息传递到HUD。在项目完成后,您将拥有类似以下的成果:
在这个简短的游戏范例中,玩家按下键时将在角色蓝图中生成一个可破坏静态网格体。石块生成和发射的位置将在放置于关卡内的生成点之中随机进行选择,因此我们必须将生成位置从关卡传输给角色蓝图。 我们还将获取保存在角色蓝图中的信息(扣动扳机的次数或剩下要发射的石块、每次扣下扳机剩余的子弹数量和玩家得分),并将此信息传递到HUD,使其显示在屏幕上。 读完本教程后,开发人员将了解以下内容:
-
需要的资源和角色设置
-
生成可射击岩石
-
从关卡传递信息到角色
-
摧毁岩石
-
通过HUD进行通信 在这一页上,我们将做一些准备工作,并设置本指南后面需要使用的资源。我们将创建一个可破坏的静态网格体,放置一些生成位置,并创建一个基本的HUD,以向玩家显示有关游戏状态的信息。
在本指南中,我们在启用 初学者内容包(Starter Content) 的情况下基于 蓝图第一人称(Blueprint First Person) 模板创建了一个新项目。如果您不确定如何基于模板创建项目或如何启用初学者内容包(Starter Content),请参阅 创建新项目 文档了解有关设置项目的信息。
创建并打开项目后,按 Ctrl+N 创建一个 新关卡(New Level) ,并在弹出窗口提示时选择 默认(Default) 。一旦您创建了一个新的关卡,请按照下面的部分开始设置各个必需的资源。
1. 必需的资源设置
创建可破坏的静态网格体
首先我们将创建可射击岩石,当我们击中它时,它将被摧毁。
-
在 内容浏览器(Content Browser) 中,打开 Content/StarterContent/Props 文件夹。
-
在 道具(Props) 文件夹中, 右键单击 SM_Rock 并选择 创建可破坏的网格体(Create Destructible Mesh) 。
-
打开 SM_Rock_DM 资源,然后从工具栏单击 破裂网格体(Fracture Mesh) 按钮。
如果在预览窗口中没有看到岩石,则关闭窗口并重新打开它。
-
保存(Save) 并关闭 SM_Rock_DM 资源。
-
右键单击 SM_Rock_DM 资源,然后选择 资源操作/使用此...创建蓝图(Asset Actions/Create Blueprint Using This...) .
当出现提示时,给蓝图命名,例如 BP_Rock 。
-
当蓝图打开时,单击 添加组件(Add Component) 按钮,然后添加一个 发射物移动(Projectile Movement) 组件。
-
单击 发射物移动(Projectile Movement) 组件,然后在 细节(Details) 中将 X 的 初始速度(Initial Speed) 、 最大速度(Max Speed) 和 速度(Velocity) 设置为 1500.00 。
-
选择 可破坏物 组件,然后在 碰撞(Collision) 下的 细节(Details) 面板中,选中 模拟生成碰撞事件(Simulation Generates Hit Events) 选项。
-
单击 编译(Compile) 和 保存(Save) 按钮,然后关闭蓝图。
放置生成点
接下来,我们将在要启动可射击岩石的关卡中创建一些生成点。
-
从 模式(Modes) 菜单中,搜索 目标点(Target Point) 并将其添加到关卡。
-
在关卡中选择 目标点(TargetPoint) ,并设置其 变形(Transform) ,如下所示。
X 的 位置(Location) 为 7.0m、0.0m、0.0m , 旋转(Rotation) 为 0.0、40.0、0.0 。
输入7.0m,即可将该值转换为700cm,即等值。检查"VR最佳实践(VR Best Practies)"页面上的 世界场景比例 部分,因为它给出了如何计算虚幻单位以及如何更改测量值显示方式的细分。
-
在关卡中,选择 目标点(Target Point) ,按下 Ctrl+W 复制它并设置其 细节(Details) ,如下所示。
这将把生成点移动到第一个生成点的左边。
-
再次按下 Ctrl+W 复制 目标点(Target Point) ,并设置新目标点的 细节(Details) ,如下所示。
-
在关卡中选择 玩家出生点(PlayerStart) ,然后按下 E 进入 旋转(Rotation) 模式,旋转它以使其面对目标点。
您现在将有三个生成点在玩家出生点对面(蓝色箭头指示控制器图标和方向)。
创建HUD
最后一部分的设置需要我们创建一个基本HUD来与之通信。
-
在 内容浏览器(Content Browser) 中的空白空间内, 右键单击 并选择 用户界面/控件蓝图(User Interface/Widget Blueprint) 。
控件蓝图(Widget Blueprint) 是一种与用于创建HUD元素的 虚幻示意图形UI(Unreal Motion Graphics UI) 一起使用的蓝图类型。
请参阅 UMG UI设计器 了解更多信息。
-
收到提示时,将其命名为 HUD ,然后打开它。
-
在 面板(Panel) 下的 调色板(Palette) 窗口中,将一个 垂直方框(Vertical Box) 拖动到 层级(Hierarchy) 窗口中的 画布面板(CanvasPanel) 上。
-
此外,在 面板(Panel) 下,将一个 水平方框(Horizontal Box) 拖动到 层级(Hierarchy) 窗口中的 垂直方框(Vertical Box) 上。
-
在 调色板(Palette) 中的 通用(Common) 部分中,将两个 文本(Text) 控件拖动到 层级(Hierarchy) 窗口中的 水平方框(Horizontal Box) 上。
-
在 层级(Hierarchy) 窗口中选择 垂直方框(Vertical Box) ,然后在 细节(Details) 面板中,单击 锚点(Anchors) 并选择其中一个锚点,如下所示。
锚点(Anchor) 将把UI元素锁定到指定位置,而不论屏幕大小如何(请参阅 锚 了解更多信息)。
-
选择 垂直方框(Vertical Box) 后,将其移动到屏幕右侧并重新调整其大小,以便显示文本。
-
单击框中最左边显示的文本,然后在 文本(Text) 下的 细节(Details) 面板中输入"Pulls:"。
-
对于其他文本,为其 文本(Text) 字段输入"10"。
此文本是我们稍后会根据游戏状态进行通信和更新的内容。
-
在 层级(Hierarchy) 窗口中, 右键单击 并 复制(Copy) 水平方框(Horizontal Box) ,然后将其粘贴到 垂直方框(Vertical Box) 顶部。
-
重复上一个步骤,从而使 垂直方框(Vertical Box) 下有三个 水平方框(Horizontal Box) ,且文本显示如下。
-
更新其他文本字段至"射击次数(Shots)"(设置为"3")和"分数(Score)"(设置为"0"),并单击 编译(Compile) 按钮。
-
编译(Compile) 并 保存(Save) ,然后关闭HUD控件蓝图。
2. 角色设置
接下来,我们会通过添加变量来完成对角色蓝图的设置,该变量稍后将在本指南中被传递到HUD。我们还会添加一些条件来确定玩家可射击所发射岩石的次数。
-
在 Content/FirstPersonBP/Blueprints 下的 内容浏览器 中,打开 第一人称角色 蓝图。
-
在图表中,删除 Stick Input 、 Movement Input 和 Jump 部分,这样您看到的就如下图所示。
对于示例游戏来说,我们只需让玩家转身和射击,因此我们移除了其他脚本来让蓝图看起来更简洁。
-
在图表中 右键单击 并搜索和添加 Event Begin Play 节点。
-
拖动 Event Being Play 节点,然后搜索并添加 Create Widget 节点。
我们会在开始玩游戏时调用 HUD 控件蓝图并显示它。
-
在 类(Class) 的 Create Widget 节点上,选择 HUD ,然后关闭 返回值(Return Value) ,使用 Add to Viewport 节点。
现在会显示出HUD,我们需要创建一些变量来传递给它。让我们现在进行此操作。
-
在 我的蓝图(MyBlueprint) 窗口中,单击 添加变量(Add Variable) 按钮。
-
选择新变量,然后在 细节(Details) 面板中,将其重命名为 IsActive 并确认其为 布尔(Boolean) 类型。
-
创建另一个变量,将其重命名为 SpawnLocation 并设置其类型为 变换(Transform) 。
该变量将被用于告知岩石生成的位置并从关卡处进行更新。
-
创建另一个变量,将其重命名为 Pulls 并设置其类型为 整数(Integer) 。
该变量将会保存玩家按下按钮后生成的剩余岩石数量。
-
再创建两个 整数(Integer) 变量,一个名称为 Shots ,另一个名称为 Score 。
您添加的变量应该看起来和上方内容类似。
-
单击 编译(Compile) 按钮,然后在 Pulls 的 细节(Details) 面板中,将其 默认值(Default Value) 设置为 10 。
-
设置 Shots 的 默认值(Default Value) 为 3 ,设置 Score 为 0 。
武器发射设置
在这里,我们要对玩家每次扣动扳机能开枪的次数进行小小的变更。
-
搜索 InputAction Fire 事件并从其拖出一根引线,然后添加 Do N 节点。
该节点会对脚本执行指定次数(从而让我们可以控制玩家射击的次数)。
-
我们把 N 设置为 3 ,然后在按住 Alt 的情况下,把 Shots 变量从 我的蓝图(My Blueprint) 窗口中拖入,然后重新连接节点。
在连接 Shots 节点后,把 Set 连接回 Montage Play 节点。
-
在按住 Control 不放的情况下,再次拉入 Shots 变量,并将其连接到 Integer - Integer 节点(设置为 1 ),然后按照显示内容进行连接。
在这里,我们把射击次数设置为每次按下 Fire 时都-1。
-
右键单击 Shots 旁的图表,然后添加名称为 ResetShots 的 自定义事件(Custom Event) 。
-
按住 Alt ,拉入 Shots ,并将其设置为 3 ,然后先连接 自定义事件(Custom Event) ,再连接到 Do N 节点的 重设(Reset) 。
当调用这个自定义事件时,它会把射击次数设置回3,然后重设DoN节点,这样就可以再次执行它。
3. 生成可射击岩石
接下来,我们将设置使玩家能够按下按钮以生成可射击岩石的逻辑(假如已满足其他条件)。在我们的关卡中,我们已定义了一些生成点,并且为了得到其中一个生成点的位置,我们将使用 事件调度器(Event Dispatcher) ,它将在 关卡蓝图(Level Blueprint) (将在下一步中创建)中触发一个事件以获取这些位置,并将其发送给角色蓝图。
-
在 第一人称角色(FirstPersonCharacter) 蓝图中, 右键单击 图表中的一个空白位置并添加一个 F 键事件。
-
按住 B 并在图表中 单击 以创建 分支(Branch) 节点。
-
按住 Alt 并拖动到 IsActive 变量中,选中复选框,然后进行连接,如下所示。
-
按住 Control 并拖动到 IsActive 和 Pulls 变量中。
-
将 IsActive 连接到 非布尔(NOT Boolean) 节点(非真),并将 Pulls 连接到 > 节点(设置为0)。
在旧版本引擎中, 非布尔(NOT Boolean) 节点指的是 != 节点
-
将两个输出连接到一个 与(And) 节点,并将其输入到 分支(Branch) 的 条件(Condition) 中。
这里我们建立了逻辑,以通过检查名为 IsActive 的变量是否为真以及玩家的 Pulls 计数是否大于0来确定玩家是否可以生成岩石。如果这两个语句都为真,我们将继续处理 分支(Branch) 节点的 真(True) 侧,并生成岩石(脚本的这一部分仍然需要设置,我们将在下面进行设置)。
-
按住 Alt 并拖动到 Pulls 变量中,并将其连接到 设置IsActive(Set IsActive) 节点。
-
按住 Control 并拖动到 Pulls 变量中,并将其连接到 整型 - 整型(Int - Int) 节点(设置为1)并连接到 设置Pulls(Set Pulls) 。
-
单击 编译(Compile) ,然后从 设置Pulls(Set Pulls) 节点添加 重置射击次数(ResetShots) 自定义事件。
您的设置看上去应与下图类似。
有关玩家何时可以生成岩石的逻辑已经设置,现在我们需要与关卡通信以获取生成位置。我们将通过使用 事件调度器(Event Dispatcher) 来实现这一点,该调度器将在按下 F 时被调用。 关卡蓝图(Level Blueprint) 将侦听事件调度器,当它被调用时,将触发它自己的事件,该事件将获取一个生成点的位置,并将其传递回角色蓝图。
-
单击 我的蓝图(My Blueprint) 窗口中的 + 事件调度器(+ Event Dispatcher) 按钮。
-
单击新的事件调度器,并按 F2 选中并将其重命名为 GetSpawnLocation 。
-
在图表中的 重置射击次数(Reset Shots) 函数后面,添加 调用GetSpawnLocation(Call GetSpawnLocation) 节点。
事件调度器随即添加,并通过节点右上角的信封图标表示。
-
关闭 GetSpawnLocation 节点,添加 从类生成Actor(Spawn Actor from Class) 节点。
-
在 生成Actor(Spawn Actor) 节点上,将 类(Class) 设置为 BP_Rock 。
-
同时在 生成Actor(Spawn Actor) 节点上,将 SpawnLocation 变量拖放到 SpawnTransform 引脚上。
我们的角色蓝图现在已被设置为生成可射击岩石,并将接收要生成岩石的 变形(Transform) 位置。
4. 从关卡传递信息到角色
接下来,我们将使用 关卡蓝图(Level Blueprint) 获取我们的一个生成点的位置,并在我们的角色蓝图的事件调度器被调用时将该信息传递给我们的角色蓝图(因此我们将从角色蓝图转到关卡蓝图,并返回角色蓝图,在这两者之间传递信息)。
-
在主编辑器(Main Editor)视图的工具栏中,单击 蓝图(Blueprints) 按钮并选择 打开关卡蓝图(Open Level Blueprint) 。
-
在图表中, 右键单击 并添加 Event Begin Play 节点以及 Get Player Character 节点。
-
从 Get Player Character 拖出 返回值(Return Value) ,并添加一个 Cast To FirstPersonCharacter 节点。
这里我们使用 Cast 节点来首先获取玩家角色,然后获取由该玩家使用的角色蓝图(本例中被称为 第一人称角色(FirstPersonCharacter) ,并且我们使用它来为可玩角色设置其它脚本)。使用Cast节点,我们得以访问玩家角色的蓝图以及变量、事件和其中的函数。
关于 投射(Casting) 的更多信息,请参阅蓝图中的转换文档页面。
-
按照下图显示内容来连接节点,然后在 Cast To 节点的 返回值(Return Value) 处,选择 提升为变量(Promote to variable) 。
我们会创建一个变量,从而保存对玩家正在使用的 第一人称角色(FirstPersonCharacter) 蓝图的引用,这样我们就不必每次使用Cast来获取结果。凭借在开始播放事件(Event Begin Play)时执行此操作,它将会在稍后为我们节省时间。
-
选择提升的变量,然后在 细节(Details) 面板中,将其重命名为 我的角色(MyCharacter) 。
-
将 MyCharacter 节点的 返回值(Return Value) 拖出,并添加 Assign Get Spawn Location 节点。
这就是我们创建的 事件调度器(Event Dispatcher) 。当您选择它时,将会添加两个额外的节点。
如果您在列表中没有看到这个节点,请确认您单击了 第一人称角色(FirstPersonCharacter) 蓝图中的 编译(Compile) 并再次尝试。
-
请确认您连接了 绑定事件(Bind Event) 的新增加节点。
现在,当我们在角色蓝图中调用 GetSpawnLocation 时,也会同时调用这个新的自定义事件。
-
按住 Control 键,从 我的蓝图(MyBlueprint) 窗口中拖入 MyCharacter 变量,然后添加 设置生成位置(Set Spawn Location) 节点。
-
返回主编辑器(Main Editor)窗口,并在 世界大纲视图(World Outliner) 中,搜索并通过按住 Ctrl 并单击来选择每个 目标点(Target Points) 。
-
返回 关卡蓝图(Level Blueprint) ,并在图表中 右键单击 并选择 创建到3个选定Actor的引用(Create References to 3 selected Actors) 。
-
在图表中 右键单击 并添加 Make Array 节点,然后将其与每个 目标点(Target Points) 连接。
您可以单击 添加引脚(Add Pin) 按钮来添加更多引脚。这个数组会存储我们可以访问的目标点集合。
-
从 数组(Array) 引脚拖出,添加一个 Get 节点。
-
从 Get 拖出,添加一个 Random Integer in Range 节点,并将 最小值(Min) 设置为"0",并将 最大值(Max) 设置为"2"。
这里我们获得了可用作生成点的随机目标点。如果您有更多的生成位置,您可以将它们添加到数组中,并增大Random Integer in Range节点中的 最大值(Max) 从而包含它们。
-
从 Get 节点拖出,添加 Get Actor Transform 节点,并将其连接到 Set Spawn Location 节点。
您的完整脚本应该和上图类似,请单击以查看大图。
5. 摧毁岩石
在本步骤中,我们会让岩石在被玩家发射的发射物击中时被摧毁。为了完成这项目标,我们会使用另一个 绑定事件(Bind Event) ,但我们不会将其绑定到事件调度器。我们会转而使用一个名称为 OnHit 的碰撞事件,它会在岩石被某种适合情境的东西射中时触发。
让我们开始射击吧!
-
返回到 第一人称角色(FirstPersonCharacter) 蓝图中,在我们生成岩石的位置处找到 Spawn Actor 节点。
-
从 Spawn Actor 节点的 返回值(Return Value) 拖出一根引线,并选择 在Actor碰撞时分配(Assign On Actor Hit) 。
-
连接 生成Actor(Spawn Actor) 和 绑定事件(Bind Event) 。
-
从 Spawn Actor 的 返回值(Return Value) 拖出一根引线,并选择 应用半径伤害(可破坏物体)(Apply Radius Damage (Destructible)) 。
我们可以使用 应用伤害(Apply Damage) ,但还需要输入一些额外的参数。为了简单起见,我们会使用半径伤害(Radius Damage)。
-
在 Apply Radius Damage 节点上,对下方显示的每个字段都输入 50000 ,然后连接 Get Actor Location 节点。
这样我们就可以对岩石做出足够大的伤害,从而让岩石碎成一块一块。
-
在 Apply Radius Damage 节点后,添加一个 Set Score 节点。
-
按住 Control 并拖动到 Score 变量中,然后将其连接到 Int + Int 节点(设置为1)并连接节点。
这样我们就可以获得当前的分数,并在岩石每次被撞击时增加1的值。
-
将 Bind Event 和 Set Score 节点连接到一个 Delay 节点,该节点设置为 3 秒。
3秒后,当岩石生成后(无论其是否被击中),我们都会销毁它。
-
在 Delay 节点后添加一个 Destroy Actor 节点。
从 Spawn Actor 节点的 返回值(Return Value) 拖出一根引线,然后连接到 Destroy Actor 节点的 目标(Target) 。
-
在 Destroy Actor 节点之后,添加 Set IsActive 变量节点,并将其保持为未选中状态。
也就是说,生成的岩石不再处于激活状态,这样玩家可以生成另一块岩石(如果他们有足够的扳机扣动次数残留的话)。
这样核心游戏进程就设置完成了,如果我们现在要在编辑器中进行播放,您可以看到,您可以显示生成、射击和销毁在关卡中的随机生成点生成的岩石。
6. 使用HUD通信
最后一步是通过与角色蓝图进行通信来获得Pulls、Shots和Score中存储的值,从而更新显示于HUD控件蓝图上的值。为完成这个目标,我们使用 Cast 节点来访问玩家的角色蓝图,然后绑定HUD中的属性到角色蓝图中的值,这样它们会在这些值在角色蓝图中更新时自动获取更新。
游戏快完成了,最后让我们更新一下HUD。
-
打开您创建的 HUD 控件蓝图。
-
打开您的 HUD 控件蓝图中的 图表(Graph) 选项卡。
-
在图表中 单击右键 并添加 Event Construct 节点。
该节点类似于 Event Begin Play 节点,并且会在控件蓝图被构建时进行调用。
-
添加一个 Get Player Character 节点和 CastTo FirstPersonCharacter 节点。
-
从 作为第一人称角色(As First Person Character) 引脚,选择 提升至变量(Promote to variable) 并将新节点重命名为 MyCharacter 。
您可以选择变量并按下 F2 来从 我的蓝图(My Blueprint) 窗口重命名变量。
-
在 设计器(Designer) 选项卡上,单击 Pulls 的值,然后在 细节(Details) 面板中的 文本(Text) 旁边,单击 绑定(Bind) 选项,并选择 创建绑定(Create Binding) 。
这将会为绑定打开一个新的图表。
-
按住 Control 并拖入 MyCharacter 变量,然后从 Get Pulls 拖出一根引线并将其连接到 Return Node 的 返回值(Return Value) 。
将自动创建 To Text (Int) 转换节点。我们现在已经可以正确显示Pulls的值。
-
在 设计器(Designer) 选项卡上,单击 Shots 的值,然后在 细节(Details) 面板中,单击 绑定(Bind) 选项,并创建下方的绑定。
这样将会更新并显示每次扣扳机时剩余的子弹数量。
-
在 设计器(Designer) 选项卡上,单击 Score 的值,然后在 细节(Details) 面板中,单击 绑定(Bind) 选项,并创建下方的绑定。
最终,它会在撞击到岩石时为玩家获取并显示合适的分数。
-
单击 编译(Compile) 和 保存(Save) ,然后关闭蓝图。
-
在主编辑器(Main Editor)视图中,单击 运行(Play) 按钮以在编辑器中运行。
您的简单射击场游戏已经完成了!要生成一个岩石,按下 F ,我们在前一节中绑定它来执行该事件。在这个指南中,我们学习了如何使用 事件调度器(Event Dispatcher) 、 Cast 节点和 绑定(Binding) 来在三种不同类型的蓝图间通信。我们学习了如何从关卡向角色蓝图传递信息,以及如何从角色向HUD进行变量通信。
7. 看你的了!
使用本项目的过程中学到的内容,尝试进行如下操作:
-
在 第一人称角色(FirstPersonCharacter) 蓝图中,对首次、第二次或第三次击中岩石给予更高的分数。
-
同时在 第一人称角色(FirstPersonCharacter) 蓝图中,将其设置为除非生成岩石,否则玩家无法进行射击。
-
在关卡中,再添加两个生成点(可能在角落,或在玩家的左/右侧)。
-
在HUD中,添加新分类来追踪记录玩家的"首次射击"命中数量。
如需获得本指南涵盖的主题以及整个编辑器的更多信息,请参阅 虚幻编辑器手册 。
关于本指南中主题相关的信息: