这篇主要分享一下如何在UE4中实现游戏中的近战攻击判定的方法之一——“射线检测”,。
首先来说一下实现的逻辑:
1.我们会在武器上设置若干个射线发射点
2.当我们攻击的时候,游戏中的每一帧都会保存武器上射线发射点的位置
3.射线的发射方向就是当前帧的射线发射点的位置到上一帧我们保存的射线发射点位置
4.射线检测到了对象,那么造成伤害。
*大致原理就是这样,具体要注意的细节在下面慢慢解释。
第一步——在武器上添加射线的发射点socket:
1.首先在UE4打开我们要用的武器的模型,点击Create Socket按钮,添加若干个Socket,
2.之后我们再把Socket移动到我们希望发射射线的地方。
3.然后在我们要用的角色的骨骼上添加武器Socket来安装武器,在Preview上选择我们要的武器来进行预览,预览还可以进行动画预览演示。
4.然后在我们的角色蓝图中添加武器。
这样一来我们的角色初步设置(武器添加Socket作为射线发射点,角色添加武器)算是搞定了!
Step2——给敌人添加一个能被攻击的interface(接口)
1.创建一个接口,有这个接口类的表示可以被攻击
2.给我们的BP_Enemy加上接口
3.然后再实现这个函数,如果被攻击检测到,就调用这个接口函数表示敌人被攻击到。
Step3——制作HitHandlerComponent(攻击判定组件):
制作一个组件的最主要目的是为了程序的复用性,只要编写一个组件,就可以给不同的角色添加,加入攻击判断功能。
然后在此之前再梳理一下我们要实现的射线检测功能的需求,就是在玩家攻击的时候启动射线检测来检测物体,这里我用的是刀,那么就应该是在刀挥下去的那一段动作序列帧我们进行射线检测,所以大概逻辑就是
1.判断是否是刀挥下去的那一刻(这个后面再动画蒙太奇里面处理)
2.是的话我们就要开启射线检测,不是就关闭
3.射线的发射方向是当前武器上的Socket节点位置到上一帧的Socket节点位置
4.射线检测到敌人,调用敌人身上的GetHit函数
逻辑是这样,具体实现和一些细节处理下面会说
1.创建组件
2. 给Component创建一个MeshComponent用来保存武器;
创建一个bool变量TraceOpen来表示是否开启射线检测;
创建一个Name数组来保存武器上所有Socket的名字;
再创建一个SocketName 与Location 的Map,存储每一个Socket对应的位置。
自定义一个初始化Component中的数据的事件。
3.在创建两个自定义事件EnableTrace和DisableTrace,分别在攻击检测开始和攻击检测结束的时候调用。
4.创建一个Trace事件,这个就是从武器上所有Socket的当前位置发射到上一帧的武器上的Socket位置的逻辑,用的Trace是MultiLineTrace
5.继续完成Trace事件,这里主要做的工作是检测所有被射线打到的Actor,判断这个Actor是否有CanBeDamaged接口,有就说明这是可以被造成伤害的,r然后我们就是要判断是否已经造成过一次伤害了,造成过伤害的Actor我们就不用再次伤害,所以这里我们要再创建一个Actor数组来保存我们已经造成过伤害的敌人,并且在之前我们可以在射线检测的时候忽略这些已经造成伤害的Actor。然后就是再每次攻击开始的时候我们要清空这个数组,然后顺便把自己给添加进去,防止打自己,最后就是在开启Trace的时候要设置一下帧武器节点的位置
6.攻击的每一帧我们要保存当前帧的Socket位置来作为下一帧射线的终点,所以所以在创建一个事件UpdateTrace来更新SocketLocation。
7.HitHandlerComponent的最后一步,当Trace打开的时候,每一帧都检测,每一帧结束之后UpdateTrace
Step4——在动画中开启和关闭射线:
(具体如何使用蒙太奇可以参考其他博客或教学视频)
这一步的目的是让射线检测精准的在动作挥刀下去的那一段序列帧进行射线检测,要用到动画通知(Animation Nofity)具体步骤如下:
1.创建一个蓝图类,类为AnimNotifyState,命名为ANS_Hit动画通知有两种,一种是执行一次的AnimNotify和可以持续执行的AnimNofityState,这里我们因为要用到一个动画序列,所以我们用第二种。
2.创建一个攻击的动画蒙太奇,找到我们攻击挥下刀的那一帧,右键添加AnimNotifyState可以找到我们之前创建的ANS_Hit,添加进去。
3.添加完后拖动来调整范围,范围就是攻击挥下刀的那一段动画,这样就算是处理完了动画通知,接下来就去ANS_Hit类来编写这个通知我们具体要通知做什么事情。
4.打开ANS_Hit我们法线这里重载了4个函数,这是所有AnimNotifyState都有的,我们主要要用到的是Received Notify Begin 和Received Notify End,这两个重载函数分别会在动画通知序列那一段的开头和结尾调用。
5.分别编写这两个函数,获取Owner然后在根据Component类来获取我们之前写好的HitHandlerComponent,在Begin的时候调用EnableTrace,End的时候调用DisableTrace.
Step5——调试:
1.给我们的玩家角色添加上HitHandlerComponent
2.开始游戏的时候初始化,调用HitHandlerComponent的Init Weapon Socket事件
3.设置敌人的碰撞体,把Visibility设置成Overlap,这样射线就可以检测到敌人了。
4.让射线可以被看到
然后这就是最终结果,over
本人自己再边写博客边做的过程中也出了点小BUG,中间会有改动的部分可能没有再文中说到,如果发现BUG请见谅,本文主要是分享一下射线检测的思路和制作方法。