UE-FPS

学习内容

  • 创建一个可以移动和环顾四周的第一人称 Pawn
  • 创建一把枪并将其附加到玩家 Pawn
  • 使用线迹(也称为射线投射)发射子弹
  • 对Actor施加伤害

您可以在此处下载已完成的项目。 

入门

下载启动项目并解压缩。导航到项目文件夹并打开BlockBreaker.uproject。您将看到以下屏幕:

绿墙由多个目标组成。当他们受到伤害时,他们会变成红色。一旦他们的健康达到零,他们就会消失。红色按钮将重置所有目标。

首先,您将创建玩家的 Pawn。

创建玩家 Pawn

导航到Blueprints文件夹并创建一个新的Blueprint Class。选择Character作为父类并将其命名为BP_Player

Character是 Pawn 的一种类型,但具有附加功能,例如CharacterMovement组件。

该组件自动处理行走和跳跃等运动。您只需调用适当的函数,它就会移动 Pawn。您还可以在此组件中设置步行速度和跳跃速度等变量。

在让 Pawn 移动之前,它需要知道玩家何时按下移动键。为此,您将移动映射到W、A、S和D键。

注意:如果您不熟悉映射,可以在我们的蓝图教程中了解它们。键映射是您定义哪些键将执行操作的方式。

创建运动映射

选择 Edit\Project Settings并打开 Input 设置。

创建两个名为MoveForwardMoveRight Axis Mappings。MoveForward 将处理向前和向后移动。MoveRight 将处理左右移动。

对于MoveForward,将键更改为W。之后,创建另一个密钥并将其设置为S将S的Scale更改为-1.0。

注意:如果您想了解Scale字段,请阅读我们的蓝图教程。 Axis Value and Input Scale 部分描述了它是什么以及如何使用它。

稍后,您将scale value 与 Pawn 的forward vector相乘。如果比例为正,这将为您提供一个指向前方的向量。如果比例为负,则向量将向后指向。通过使用生成的向量,您可以使您的 Pawn 向前和向后移动。

接下来,您需要对左右移动执行相同的操作。将MoveRight的键更改为D。之后,创建一个新密钥并将其设置为A。将A的Scale 更改为-1.0。

现在您已经设置了映射,您需要使用它们来移动。

实施运动

打开BP_Player并打开事件图表。添加一个MoveForward(在Axis Events下列出的那个)事件。即使您不按任何内容,此事件也会在每一帧执行。

它还将输出一个Axis Value,这将是您之前设置的Scale值。如果按W它将输出1,如果按S它将输出-1。如果您不按任何一个键,它将输出0。

接下来,您需要告诉 Pawn 移动。添加一个Add Movement Input并像这样连接它:

Add Movement Input将采用一个向量并将其乘以Scale Value。这会将其转换为适当的方向。由于您使用的是CharacterCharacterMovement组件会将 Pawn 朝该方向移动。

现在,您需要指定要向哪个方向移动。既然要向前移动,可以使用Get Actor Forward Vector。这将返回一个指向前方的向量。创建一个并像这样连接它:

概括:

  1. MoveForward将运行每一帧并输出一个Axis Value。如果您按W,此值将为1 ,如果按S此值为-1。如果您不按任何一个键,它将是0。
  2. Add Movement Input 会将 Pawn 的 forward vectorScale Value相乘。这将导致矢量指向前方或后方,具体取决于您按下的键。如果不按任何键,矢量将没有方向,这意味着 Pawn 不会移动。
  3. CharacterMovement组件将从Add Movement Input获得结果。然后它将向那个方向移动 Pawn。

MoveRight重复该过程,但将Get Actor Forward Vector替换为Get Actor Right Vector。

在您可以测试移动之前,您需要在游戏模式中设置默认 pawn。

设置默认 Pawn

单击编译,然后返回主编辑器。打开World Settings面板并找到Game Mode部分。将默认 Pawn 类更改为BP_Player

注意:如果您没有 World Settings 面板,请转到工具栏并选择Settings\World Settings

现在您将在游戏开始时自动使用BP_Player按Play并使用W、A、S和D键四处移动。

接下来,您将创建用于环顾四周的映射。

创建外观映射

打开Project Settings。再创建两个名为LookHorizo​​ntalLookVertical的Axis Mappings

LookHorizo​​ntal的键更改为Mouse X

当您向右移动鼠标时,此映射将输出一个正值,反之亦然。

接下来,将LookVertical的键更改为Mouse Y

当您向上移动鼠标时,此映射将输出一个正值,反之亦然。

现在,您需要创建环顾四周的逻辑。

实现查找

如果 Pawn 没有Camera组件,Unreal 会自动为您创建一个摄像头。默认情况下,此相机将使用控制器的旋转。

注意:如果您想了解有关控制器的更多信息,请查看我们的 AI 入门教程。

即使控制器是非物理的,它们仍然有自己的旋转。这意味着您可以使 Pawn 和相机面向不同的方向。例如,在第三人称游戏中,角色和摄像机并不总是面向同一个方向。

要在第一人称游戏中旋转相机,您需要做的就是更改控制器的旋转。

打开BP_Player,然后创建一个LookHorizo​​ntal事件。

要使相机向左或向右看,您需要调整控制器的yaw。创建一个Add Controller Yaw Input 并像这样连接它:

现在,当您水平移动鼠标时,控制器将向左或向右偏航。由于相机正在使用控制器的旋转,它也会偏航。

LookVertical重复该过程,但将Add Controller Yaw Input替换为Add Controller Pitch Input

如果您现在使用测试游戏,您会注意到垂直外观是倒置的。这意味着当您向上移动鼠标时,相机会向下看。

如果您更喜欢非反转控件,请将Axis Value乘以-1。这将反转Axis Value,这将反转控制器俯仰。

单击编译,然后按播放。使用鼠标开始环顾四周。

现在所有的动作和外观都完成了,是时候制作枪了!

创建枪

您知道在创建蓝图类时如何选择父类吗?好吧,您也可以选择自己的蓝图作为父级。当您拥有共享通用功能或属性的不同类型的对象时,这很有用。

假设您想要拥有多种类型的汽车。您可以创建一个包含诸如速度和颜色等变量的汽车基类。然后,您可以创建使用基汽车类作为父类的类(子类)。每个孩子也将包含相同的变量。现在,您可以轻松创建具有不同速度和颜色值的汽车。

您可以使用相同的方法来创建枪支。为此,您需要先创建一个基类。

创建基础枪类

返回主编辑器并创建一个Actor类型的蓝图类。将其命名为BP_BaseGun,然后打开它。

接下来,您将创建一些变量来定义枪的一些属性。创建以下浮点变量:

  • MaxBulletDistance:每个子弹可以行进多远
  • Damage: 当子弹击中Acto时施加多少伤害
  • FireRate:枪可以发射另一颗子弹之前的时间(以秒为单位)

注意:每个变量的默认值为零,这对于本教程来说很好。但是,如果您希望新的枪支类具有默认值,您可以在BP_BaseGun中设置它。

现在,您需要枪的物理表示。添加一个Static Mesh 组件并将其命名为GunMesh

现在不要担心选择静态网格。当您创建子枪支类时,您将在下一节中执行此操作。

创建子枪类

单击编译,然后返回主编辑器。要创建子类,请右键单击BP_BaseGun并选择Create Child Blueprint Class

将其命名为BP_Rifle,然后打开它。打开Class Defaults并将每个变量设置为以下值:

  • MaxBulletDistance: 5000
  • Damage: 2
  • FireRate: 0.1

这意味着每颗子弹最多可以移动5000距离。如果它击中一个演员,它将造成2点伤害。连续射击时,每次射击之间的持续时间至少为 0.1秒。

接下来,您需要指定枪应使用的网格。选择GunMesh组件并将其静态网格体设置为SM_Rifle

枪现在完成了。单击编译,然后关闭BP_Rifle

接下来,您将创建自己的相机组件。这将使您更好地控制相机的位置。它还允许您将枪连接到相机,这将使枪保持在相机前面。

创建相机

打开BP_Player,然后创建一个Camera组件。将其命名为FpsCamera

默认位置有点太低,可能会让玩家觉得自己很小。将FpsCamera位置设置为(0, 0, 90)

默认情况下,Camera 组件不使用控制器的旋转。要解决此问题,请转到 Details 面板并启用Camera Settings\Use Pawn Control Rotation

接下来,您需要定义喷枪的位置。

定义喷枪位置

要创建枪位置,您可以使用Scene组件。这些组件非常适合定义位置,因为它们只包含一个变换。确保您选择了FpsCamera,然后创建一个Scene组件。这会将其连接到相机。将其命名为GunLocation

通过将GunLocation附加到FpsCamera,枪将保持相对于相机的相同位置。这就是您始终将枪保持在镜头前的方式。

接下来,将GunLocation位置设置为(30, 14, -12)。这将把它放在前面,稍微放在相机的侧面。

然后,将旋转设置为(0, 0, -95)。当您安装枪时,这将使它看起来好像瞄准屏幕的中心。

现在,您需要生成枪并将其附加到GunLocation

生成和连接枪

找到Event BeginPlay并从 Class 创建一个Spawn Actor。将类设置为BP_Rifle

由于您稍后需要使用枪,因此您应该将其存储在一个变量中。创建一个BP_BaseGun类型的变量并将其命名为EquippedGun

重要的是变量不是BP_Rifle类型。这是因为玩家可以使用不同类型的枪,而不仅仅是步枪。如果您生成了不同类型的枪,您将无法将其存储在BP_Rifle类型的变量中。这就像试图将一个圆圈放入一个矩形孔中。

通过创建BP_BaseGun类型的变量,您正在创建一个可以接受许多形状的大洞。

接下来,将EquippedGun设置为Spawn Actor From Class返回值

要连接枪,您可以使用AttachToComponent。创建一个并将Location RuleRotation Rule设置为Snap to Target。这将使枪具有与其父级相同的位置和旋转。

接下来,创建对GunLocation的引用并像这样连接所有内容:

概括:

  1. BP_Player生成时,它将生成一个BP_Rifle实例
  2. EquippedGun将保留对生成的BP_Rifle的引用以供以后使用
  3. AttachToComponent将枪附加到GunLocation

单击编译,然后按播放。现在,当您生成时,您将拥有一把枪!当你环顾四周时,枪总是在镜头前。

现在是有趣的部分:射击子弹!要检查子弹是否击中某物,您可以使用line trace

射击子弹

线迹是一个接收起点和终点(形成一条线)的函数。然后它将检查沿线的每个点(从开始到结束),直到它碰到某些东西。在游戏中,这是检查子弹是否击中某物的最常用方法。

由于射击是枪支的一项功能,因此它应该属于枪类而不是玩家。打开BP_BaseGun并创建一个名为Shoot的函数。

然后,创建两个Vector输入并将它们命名为StartLocationEndLocation。这些将是线迹的起点和终点(您将从BP_Player 传入)。

您可以使用LineTraceByChannel执行线跟踪。该节点将使用可见性或相机碰撞通道检查命中。创建一个并像这样连接它:

接下来,您需要检查线路跟踪是否命中任何内容。创建一个 Branch并像这样连接它:

如果有命中,返回值将输出true,反之亦然。

为了给玩家一些关于子弹击中位置的视觉反馈,您可以使用粒子效果。

产生子弹冲击粒子

首先,您需要获取跟踪命中的位置。拖动单击Out Hit并释放图表中的左键单击。从菜单中,选择Break Hit Result

这将为您提供一个具有与线迹结果相关的各种引脚的节点。

Location创建一个Spawn Emitter并将Emitter Template设置为PS_BulletImpact。之后,将其位置连接到Break Hit Result的位置。

这是到目前为止的功能:

概括:

  1. 当Shoot执行时,它将使用提供的起点和终点执行线跟踪
  2. 如果有击中,位置的Spawn Emitter将在击中位置生成PS_BulletImpact

现在Shoot Function逻辑已经完成,就需要使用它了。

调用Shoot Function

首先,您需要为拍摄创建一个键映射。单击编译,然后打开Project Settings。创建一个名为Shoot Axis Mapping。将其键设置为Left Mouse Button,然后关闭Project Settings

之后,打开BP_Player并创建一个Shoot事件。

要检查玩家是否按下了Shoot键,您只需要检查Axis Value是否等于1。创建突出显示的节点:

接下来,创建对EquippedGun的引用,然后调用它的Shoot函数。

现在您需要计算线迹的起点和终点。

计算线迹位置

在许多 FPS 游戏中,子弹从相机而不是枪开始。这是因为相机已经与十字准线完美对齐。因此,如果您从相机拍摄,则可以保证子弹会飞到十字准线所在的位置。

注意:有些游戏确实是用枪射击的。但是,它需要额外的计算才能射向十字准线。

创建对FpsCamera的引用,然后将其连接到GetWorldLocation

现在您需要结束位置。请记住,枪具有MaxBulletDistance变量。这意味着结束位置需要是相机前面的MaxBulletDistance单位数量为此,请创建突出显示的节点:

之后,像这样连接所有东西:

概括:

  1. 当玩家按下或按住左键时,枪会从相机开始发射子弹
  2. 子弹将向前移动MaxBulletDistance指定的距离

单击编译,然后按播放。按住左键开始射击。

目前,枪正在射击每一帧。这有点太快了,所以下一步是降低枪的射速。

降低射速

首先,您需要一个变量来决定玩家是否可以射击。打开BP_Player并创建一个名为CanShoot的布尔变量。将其默认值设置为true。如果CanShoot等于true,则玩家可以射击,反之亦然。

Branch部分更改为以下内容:

现在,玩家只有在按下Shoot键并且CanShoot等于true时才能射击。

接下来,添加突出显示的节点:

变化:

  1. 玩家只有在按住左键并且CanShoot等于true时才能射击
  2. 一旦玩家射出子弹,CanShoot将被设置为false。这将阻止玩家再次射击。
  3. 在FireRate提供的持续时间之后,CanShoot将被设置回true

单击编译,然后关闭BP_Player。按播放并测试新的射速。

接下来,您将使目标和按钮响应项目符号。你可以通过对它们施加伤害来做到这一点。

施加伤害

在虚幻中,每个演员都有受到伤害的能力。但是,由您决定演员如何回应它。

例如,在受到伤害时,格斗游戏角色会失去生命值。然而,像气球这样的东西不会有健康。相反,您可以对气球进行编程,使其在受到损坏时弹出。

在处理演员如何受到伤害之前,您首先需要施加伤害。打开BP_BaseGun并在Shoot函数的末尾添加Apply Damage

接下来,您需要指定要损坏的actor。在这种情况下,它是被线迹击中的演员。将受到伤害的 Actor连接到Break Hit ResultHit Actor

最后,您需要指定要施加多少伤害。获取对Damage的引用并将其连接到Base Damage。

现在,当你调用Shoot时,它会损坏任何被线迹击中的演员。单击编译,然后关闭BP_BaseGun。

现在你需要处理每个actor如何受到伤害。

处理损坏

首先,您将处理目标如何受到伤害。打开BP_Target,然后创建一个Event AnyDamage。只要actor受到不为零的伤害,这个事件就会执行。

然后,调用TakeDamage函数并连接Damage引脚。这将从目标的Health变量中减去生命值并更新目标的颜色

现在,当目标受到伤害时,它会失去生命值。单击编译,然后关闭BP_Target

接下来,您需要处理按钮如何受到损坏。打开BP_ResetButton并创建一个Event AnyDamage。之后,调用ResetTargets函数。

当按钮受到伤害时,这将重置所有目标。单击编译,然后关闭BP_ResetButton。

按播放并开始射击目标。如果要重置目标,请按下按钮。

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值