原文:Unreal Engine 4 Blueprints Tutorial
作者:Tommy Tran
译者:Shuchang Liu

在本篇教程里,你将学会如何用蓝图系统创建玩家角色,设置输入,并编写角色通过触碰,收集道具的游戏逻辑。

蓝图是Unreal Engine 4的一套可视化脚本系统,通过蓝图可以快速制作游戏原型。你不再需要一行行的编写代码,取而代之的是可视化操作:拖拽节点,在UI里设置节点参数,给节点进行连线。

除了作为一款非常便捷的原型工具,蓝图也降低了非开发人员制作游戏逻辑的门槛。

在本篇教程,你将使用蓝图来:

  • 设置垂直视角摄像机
  • 创建具备基本移动的玩家控制器角色
  • 设置玩家输入
  • 创建可被角色触碰并收集的道具

注意:本篇教程假定你已了解Unreal Engine 4的基本操作界面。你也应该熟悉基本的蓝图概念,比如组件和节点。如果你需要复习以上内容,点击入门教程。

注意:本篇教程只是Unreal Engine 4系列教程的其中一篇:

  • Part 1:入门
  • Part 2:蓝图
  • Part 3:材质
  • Part 4:UI
  • Part 5:制作简单游戏
  • Part 6:动画
  • Part 7:音频
  • Part 8:粒子系统
  • Part 9:AI
  • Part 10:制作简单FPS游戏

起步入门

下载示例项目并解压。进入项目文件夹,双击BananaCollector.uproject打开项目。

注意:如果你看到了项目是由较早的引擎版本创建的提示,这很正常(因为引擎经常更新版本)。你可以选择以拷贝副本的形式打开,也可以直接转换项目版本打开。

你可以看到以下的场景。我们创建的角色会在场景内移动并收集道具。

为了方便起见,我已经给项目文件做了文件夹分类,如下图所示:

你可以点击红框处按钮来显示/隐藏侧边栏列表。

创建玩家

点击进入Content Browser界面的Blueprints文件夹。点击Add New按钮并选择Blueprint Class

由于玩家需要能够获取输入,Pawn类比较适合。在弹出窗口选择创建Pawn,将其命名为BP_Player

注意:选择Character类创建也可以,它还默认引入了移动组件。不过,既然我们想要自己动手实现移动,Pawn类已经足够了。

关联摄像机

摄像机是玩家观察游戏世界的方式。我们要创建一个垂直视角观察玩家角色的摄像机。

在Content Browser 双击BP_Player打开蓝图编辑器。

为了创建摄像机,在Components面板点击Add Component并选择Camera

为了让摄像机视角自顶向下,我们需要先把它放在玩家角色上方。选中摄像机组件,再切换到Viewport页签。

按下W键激活移动操作杆,将摄像机移动到(-1100, 0, 2000)。或者,你可以在Location字段输入坐标点来移动摄像机。

如果摄像机被移出界面外,按下F键就可以重新定位看到摄像机。

接着,按下E键激活旋转操作杆,将摄像机沿Y轴旋转-60度。

玩家表示

我们用一个红色方块来表示玩家,所以需要使用Static Mesh组件进行展示。

首先,在Components面板左键点击空白处取消选中Camera组件。否则,新加的组件会成为摄像机的子节点。

点击Add Component并选择Static Mesh

为了展示红色方块,选择Static Mesh组件,随后在Details页签Static Mesh属性点击下拉框,选择SM_Cube

你在关卡场景里应该就能看到如下画面(如果看不到,你可以在Viewport窗口按下F键聚焦画面)

现在,是时候在关卡里动态生成玩家了。点击Compile按钮并回到主编辑器。

生成玩家

为了让玩家能够控制角色,你需要明确两件事:

  1. 玩家所要控制的Pawn类
  2. 角色应该在哪里生成

你可以通过创建Game Mode类(游戏模式类)来实现第一点。

创建游戏模式

游戏模式是一个类,用于控制玩家进入游戏的方式。比如,在多人游戏里,可以使用游戏模式,决定每个玩家在哪里生成。更重要的是,游戏模式决定了玩家使用哪个角色。

在Content Browser里点击进入Blueprints文件夹。点击Add New按钮并选择Blueprint Class

从弹出窗口里选择Game Mode Base,并命名为GM_Tutorial

现在,你需要指定哪个Pawn作为默认类。双击GM_Tutorial打开蓝图编辑器。

留意Details面板的Classes部分。点击Default Pawn Class属性的下拉框,并选择BP_Player

其次,关卡还需要知道当前使用哪个游戏模式。你可以在World Settings里指明这一点。点击Compile并关闭蓝图编辑器。

每个关卡都有自己的设置。你可以通过Window\World Settings查看设置。同样地,也可以在Toolbar选择Settings\World Settings进行查看。

Details页签旁边就会出现World Settings页签。点击该页签的GameMode Override字段,选择GM_Tutorial

现在可以看到Game Mode类已经修改成GM_Tutorial

最后,我们还需要指定玩家的生成位置。通过在关卡里放置Player Start(玩家出生点)即可。

放置玩家出生点

在生成玩家的过程中,游戏模式会寻找关卡中是否有玩家出生点。如果有,游戏模式就会在该点生成玩家。

为了放置玩家出生点,在Modes面板搜索Player Start左键拖拽 Player Start至Viewport面板。

你可以随意放置玩家出生点。放好后,点击Toolbar的Play按钮。玩家就会在出生点生成。

如果想要退出游戏,点击Toolbar的Stop按钮或按下Esc键皆可。如果你看不到鼠标指针,按下Shift+F1

如果玩家不能控制移动,那其实算不上游戏,对吧?我们的下个任务就是设置输入控制。

设置输入

将某个按键指定成触发某个行为,称之为按键绑定。

在Unreal里,你可以通过按键触发event(事件)的方式来实现按键绑定。事件节点是一类当接收到特定行为时,触发执行的节点(比如在这个例子里,当你按下绑定按键时,触发执行某个事件节点)。当某个事件被触发时,任何跟事件节点连接的节点就会被执行。

这种按键绑定的方式非常有好处,因为这意味着你不需要硬编码按键对应的逻辑。

比如,你绑定了鼠标左键并命名为Shoot事件。任何有射击能力的Actor都可以使用Shoot事件,用于检测玩家何时按下了鼠标左键。如果你想修改射击对应绑定的按键,只要在输入设置里修改即可。

如果以硬编码方式实现,你需要遍历每个Actor,分别修改射击对应绑定的按键。

轴映射和操作映射

Edit\Project Settings里可以看到输入设置。点击Engine部分的Input选项进入设置界面。

Bindings就是用于设置输入的部分。

Unreal提供了两类按键绑定方法:

  • Action Mapping(操作映射):这类绑定只有两种状态:按下或者没按下。行为只会在按下或释放按键的时候触发。这类绑定适用于没有中间状态的行为,比如枪械射击。
  • Axis Mapping(轴映射):这类绑定输出一个称之为Axis Value(下文有更多介绍)的数字。每帧都会触发对应的轴事件。这类绑定通常用于摇杆或者鼠标。

在这篇教程里,我们会使用Axis Mapping

创建移动映射

首先,你需要创建两组Axis Mapping。这样就可以实现多按键触发同一个事件。

为了创建一组新的Axis Mapping,点击Axis Mappings右侧的+号。创建两组Axis Mapping,分别命名为MoveForwardMoveRight

MoveForward负责前后移动。MoveRight负责左右移动。

我们需要把移动映射到四个按键上:WASD。现在只有两个插槽用于映射按键。通过点击每组映射文本框右侧的+号,添加映射插槽。

接着点击每组插槽的下拉框,将WS键映射到MoveForwardAD键映射到MoveRight

接着,我们需要设置Scale字段。

Axis Value和Input Scale

在你设置Scale字段前,我们需要了解它是怎么跟axis values搭配起作用的。

Axis Value的输出数值取决于输入类型和使用方式。按钮点击会输出1。摇杆根据推动方向和力度,输出-1~1之间的数值。

你可以使用Axis Value控制角色的移动速度。比如,如果你把摇杆推到了最边上,Axis Value是1。如果你只推一半,Axis Value就是0.5。

将Axis Value跟某个速度变量进行相乘,你就能够调整摇杆的速度。

你也可以通过Axis Value判断出方向。如果你将角色速度与一个Axis Value正数相乘,得到的就是正数偏移。角色速度与一个Axis Value负数相乘,得到的就是负数偏移。将偏移值与角色位置相加,就能知道角色往哪个方向移动了。

由于键盘按键只能输出0或1的Axis Value,你可以使用Scale来将其转换成负数。通过Axis Value和Scale值相乘就可以做到这点。

如果正数(Axis Value)和负数(Scale)相乘,按键输出就是负数。

因此我们点击修改按键SAScale字段文本为-1。

接着,有趣的部分来了:让角色动起来!关闭项目设置面板,双击BP_Player打开蓝图编辑器。

角色移动

首先,你需要获取移动映射的事件。在事件图表空白处点击右键打开节点列表。从弹出菜单中搜索MoveForward。添加处于Axis Events下的MoveForward节点。注意我们要添加的是Axis Events下的红色节点,而非Axis Values下的绿色节点。

添加MoveRight节点的步骤同上。

现在,我们需要设置下MoveForward节点。

使用变量

为了实现移动,我们需要指定角色的运动速度。最简单的方法是通过变量保存移动速度。

要新建变量,我们点击My Blueprint页签Variable部分的+号。

选中新建的变量,观察Details页签。将变量名重命名为MaxSpeed。随后,点击Variable Type的下拉框选择Float,将变量类型修改为Float

接着,需要给变量设置默认值。在这之前,先点击Toolbar上的Compile按钮。

保持变量选中,在Details页签的Default Value区域,将MaxSpeed的默认值设为10

接着,将MaxSpeed变量从My Blueprint页签拖拽至Event Graph。并选择弹出菜单的Get

我们现在需要将MaxSpeedAxis Value相乘来得出最终移动速度和方向。添加float * float节点,并连接Axis ValueMaxSpeed

获取角色朝向

为了向前移动,首先需要知道角色的朝向。幸运地是,Unreal里有这样的节点。我们需要添加Get Actor Forward Vector节点。

接着,添加Add Movement Input节点。该节点通过获取方向和数值,将其转换成移动偏移值。我们按下图连接各个节点:

白线代表节点执行顺序。换言之,玩家进行操作,触发相应事件并执行InputAxis MoveForward节点,随后执行Add Movement Input节点。

Add Movement Input节点需要如下输入:

  • Target:默认为self,在这里就是玩家角色自己(红色方块)。
  • World Direction:目标移动方向,在这里就是玩家角色的朝向。
  • Scale Value:玩家移动距离,在这里为Max Speed * Axis Value(值范围为-1~1)。

MoveRight事件的设置步骤同上,除了要把Get Actor Forward Vector节点替换为Get Actor Right Vector节点。试着不对照前面的操作指引,自己动手看看!

添加移动偏移

为了让角色真正动起来,我们还需要将Add Movement Input节点计算得出的偏移值,累加到角色当前位置上。

基本上我们的策略就是让游戏角色每帧移动一点点,所以我们需要在Event Tick事件添加运动节点,每帧进行调用。

现在看看Event Graph有没有Event Tick节点,它应该处于灰化状态,如果没有就创建对应节点。

为了获取偏移值,创建Consume Movement Input Vector节点。要累加偏移值到玩家角色上,还需要添加AddActorLocalOffset节点。随后如下图连接节点:

这样意味着在游戏每帧,你会获取角色的移动输入,并将其累加在角色当前位置上。

点击Compile,回到主编辑器并点击Play。你就能操控红色方块四处移动了!

这里有个小问题。高配机器有可能运行帧率更高。由于Event Tick事件每帧调用,那同等时间内运动节点执行的次数更多。导致的结果就是高配机器角色移动得更快,反之亦然。

为了避免这个问题,角色运动必须是帧率无关的。

注意:我已经做了按键绑定用于展示帧率有关会产生的影响。按下数字键0将帧率调成60,按下数字键1将重置帧率。控制角色四处移动,看看不同帧率对移动速度的影响。

帧率无关

帧率无关意味着不管帧率是多少,相同时间的游戏运行,会产生完全一致的结果。幸运地是,在Unreal里要做到这点非常容易。

退出游戏,并打开BP_Player。接着,观察Event Tick节点的Delta Seconds字段。

Delta Seconds为当前帧的Event Tick调用与上一帧Event Tick调用的时间间隔。通过将偏移值与Delta Seconds相乘,角色运动就是帧率无关的。

比如,你的角色最高速度是100。如果距离上一帧Event Tick已经过了1秒,则角色移动100个单元。如果只过了0.5秒,则角色运动50个单元。

如果角色运动是帧率相关的,那就会产生不过帧率高低,每帧固定移动100单元的结果。

为了将偏移值与Delta Seconds相乘,添加vector * float节点。之后,如下图进行连线:

由于每帧间隔时间很短,角色移动起来会很慢,所以可以将MaxSpeed的默认值调大至600

至此恭喜你,成功解锁了帧率无关成就!

你可能注意到了,方块现在会穿透其他物体。为了解决这个问题,我们需要用上碰撞检测

角色碰撞

为了能够互相碰撞,角色需要一个代表其碰撞区域(通常称之为碰撞体)的东西。你可以使用以下任一种:

  • Collision mesh(碰撞网格):这个通常在网格导入时就会生成(如果你勾选了允许)。用户也可以用3D软件创建自定义碰撞网格。红色方块导入时就自动生成了碰撞网格。
  • Collision component(碰撞组件):一般由三种形状:盒子,胶囊体和球体。你可以通过Components面板进行添加。通常用于简单碰撞。

下面就是一个人物和其碰撞体的例子。

当一个碰撞体碰到了另个碰撞体,碰撞就产生了。

设置碰撞

你可能会奇怪,方块有碰撞体,却没有检测到碰撞。当你移动方块时,Unreal只认为方块的根组件可产生碰撞。由于方块的根组件并没有任何碰撞体,所以就穿透了其他物体。

注意:一个root组件没有碰撞体的角色,同样可以挡住其他角色。但如果你移动这个角色,它是不会与任何物体产生碰撞的。

所以,为了使用碰撞网格,StaticMesh必须作为根组件存在。我们通过在Components面板左键拖拽StaticMesh至DefaultSceneRoot。释放鼠标,StaticMesh现在就成了根组件了。

最后还要做一件事情。切换到Event Graph页签,将AddActorLocalOffset节点的Sweep输入勾选为true

简单来讲,AddActorLocalOffset会将角色从旧位置瞬移到新位置上。Sweep可以确保旧位置和新位置之间的物体都能与角色进行碰撞检测。

回到主编辑器并点击Play。现在方块能与关卡场景产生碰撞了!

创建道具

任何东西都能成为供玩家触碰拾取的道具。这里我们使用BP_Banana作为道具。

为了检测方块是否碰到了道具,我们需要一个在产生碰撞时,触发执行的事件节点。我们可以使用碰撞响应来生成事件。

碰撞响应也决定了角色之间的碰撞后行为。有以下三类碰撞响应:IgnoreOverlapBlock。以下是它们互相之间的作用结果:

虽然可以使用Overlap或Block的任一种,本篇教程只展示如何使用Overlap。

设置碰撞响应

退出游戏并打开BP_Banana。选择StaticMesh组件并观察Details面板,Collision部分可以设置碰撞响应。

如图所示,大部分设置都是灰置的。为了编辑它们,左键点击Collision Presets的下拉框,选择Custom选项。

现在,你需要指定道具和方块之间的碰撞响应。

组件有一项属性称之为对象类型。对象类型是一种给角色进行简单分类的方法。你可以在这里了解更多关于对象类型的内容。

由于方块的类型是WorldDynamic,我们需要修改该类型对象的碰撞响应。在Collision Responses设置下,左键点击WorldDynamic中间的勾选框,将碰撞响应改成Overlap

碰撞处理

为了获取碰撞情况并进行处理,我们需要用到overlap事件。在Components面板右键点击StaticMesh。从弹出菜单中,选择Add Event\Add OnComponentBeginOverlap

Event Graph界面就会出现OnComponentBeginOverlap (StaticMesh)节点。

最后,添加DestroyActor节点,并连接OnComponentBeginOverlap (StaticMesh)节点。顾名思义,该节点会将目标角色从游戏中移除。由于我们没有显式指定Target,所以它会销毁调用该节点的角色。

放置道具

关闭蓝图编辑器,并确保Content Browser打开了Blueprints文件夹。

通过左键拖拽 BP_Banana至Viewport界面来在关卡放置香蕉道具。

点击Play按钮,开始收集香蕉吧!

后续学习

你可以在这里下载完整项目。

你现在距离成为Unreal Engine专家又近了一步了。希望这篇教程没有难倒你。

如果你还想继续学习Unreal Engine 4引擎,点击下篇教程,我会进一步讲解Unreal Engine 4引擎的材质系统。

Unreal Engine 4 系列教程 Part 2:蓝图教程相关推荐

  1. Unreal Engine 4 系列教程 Part 8:粒子系统教程

    原文:Unreal Engine 4 Particle Systems Tutorial 作者:Tommy Tran 译者:Shuchang Liu 在本篇教程中,你将学习如何创建粒子特效并使用蓝图进 ...

  2. Unreal Engine 4 系列教程 Part 7:音频教程

    原文:Unreal Engine 4 Audio Tutorial 作者:Tommy Tran 译者:Shuchang Liu 在本篇教程中,你将学习如何以不同方法播放3D音效,并通过UI控制音频音量 ...

  3. Unreal Engine 4 系列教程 Part 1:入门

    原文:Unreal Engine 4 Tutorial for Beginners: Getting Started 作者:Tommy Tran 译者:Shuchang Liu 本篇教程将引导你安装U ...

  4. Unreal Engine 4 系列教程 Part 9:AI教程

    原文:Unreal Engine 4 Tutorial: Artificial Intelligence 作者:Tommy Tran 译者:Shuchang Liu 在本篇教程中,你将学习如何使用行为 ...

  5. Unreal Engine 4 系列教程 Part 3:材质教程

    原文:Unreal Engine 4 Materials Tutorial 作者:Tommy Tran 译者:Shuchang Liu 通过这篇教程,你将学会如何在材质编辑器里修改贴图,创建材质实例, ...

  6. Unreal Engine 4 系列教程 Part 5:制作简单游戏

    原文:How to Create a Simple Game in Unreal Engine 4 作者:Tommy Tran 译者:Shuchang Liu 在本篇教程中,你将学习制作一个第一人称动 ...

  7. 【Unreal Engine】UE5 虚幻引擎下载安装教程

    一.软件下载 官网下载 点击右上角下载 跳转到此页面,然后页面向下滚动 然后点击下载自动程序 ,会得到 unrealEngine EpicInstaller 的 msi 安装器 二.安装 点击 Epi ...

  8. ue5新手零基础学习教程 Unreal Engine 5 Beginner Tutorial - UE5 Starter Course

    ue5新手零基础学习教程 Unreal Engine 5 Beginner Tutorial - UE5 Starter Course! 教程大小解压后:4.96G 语言:英语+中英文字幕(机译)时长 ...

  9. 【新手必读】Unreal Engine 4 C++入门教程(上)

    原文|<Unreal Engine 4 C++ Tutorial> 作者|Tommy Tran Feb 6 2018 | 翻译 开发游戏的老王 阅读时长|25分钟 内容难度|入门 在本教程 ...

最新文章

  1. hdu 1588 Gauss Fibonacci 较难
  2. 建模算法(四)——动态规划
  3. Boost库之function的使用
  4. java基础--IO流之File类
  5. 《跟唐老师学习云网络》 - ip命令
  6. 水滴公司再回应“线下违规”:核心是公司的管理问题
  7. 随想录(fatfs的学习)
  8. MySQL8新增管理端口
  9. 如果因为断电等导致文件损坏的系统无法开启的解决办法(鸟哥私房菜)
  10. postman 测试excel下载_使用Postman轻松实现接口数据关联
  11. np.dot、np.outer、np.matmul、np.multipy、np.inner、np.outer与np.cross几个函数之间的区别
  12. 基于Pytorch对凸函数采用SGD算法优化实例(附源码)
  13. VHDL-任意分频器(50%占空比)
  14. STM32---FLASH闪存
  15. php mmorpg,MMORPG中的组队设计
  16. 切线空间?切线空间的作用到底是什么?
  17. 关于智能水表背后的“节水效应”
  18. 经典算法之左边界二分查找法(俗称左边界二分搜索法)
  19. 氧分呗:新时代定义科技的美好 自主创新踏上新征程
  20. iuap助力中建五局打造数字化创新集成平台

热门文章

  1. 海归首选“北广” 薪酬期望值不要太高 元芳你怎么看?
  2. ADS中导入SPICE模型
  3. cf不能全屏win7的解决方法_Win7系统防火墙无法设置的解决方法
  4. vue实现省市区三级联动地址选择
  5. 解决MySQL导入Excel无法打开Excel的问题
  6. 企微获取用户敏感数据
  7. oracle透明网关访问sqlserver_汽车之家从 SQL Server 到 TiDB 的异构变迁
  8. pig对null的处理(实际,对空文本处理为两种取值null或‘’)
  9. 硬件工程师需要知道的DFM可制造性设计
  10. 高德地图api district.search一直报no_data