65. UE5 RPG 实现远程攻击

前面,我们实现了敌人的近战普通攻击,还兼容了对于没有武器的敌人的攻击。有近战就要有远程,这一篇,我们实现一下敌人的远程攻击。

首先,由于创建的资源增多,我们将GA和GE按敌人和英雄的类别分开,分别在目录下面创建存放GA和GE的文件夹

这样条例会更加的清晰,方便我们后续的资源维护。

创建远程敌人技能

接下来,我们创建一个敌人的技能蓝图,继承我们之前实现的投掷技能的类ProjectileSpell类

命名为GA_RangedAttack,专门用于敌人的技能投掷

有了这个技能蓝图后,我们需要在蓝图中连节点实现播放蒙太奇,并生成发射的实例

还需要在右侧设置,Projectile Class用来设置技能生成的发射物的实例,Damage Effect Class用来设置发射物使用的GE,Damage Types用来设置技能造成的伤害的曲线,最后的标签用来设置应用以后,可以使用此标签激活技能。

伤害的计算这个我们之前写的那个比较通用,所以直接设置即可

在高级设置这里,我推荐设置每个Actor只创建一个对应的实例,如果重复激活时,结束之前的即可

创建发射物

参照之前我们实现的火球术,在技能释放后,会生成一个发射物体,也就是火球。

敌人发射的是石头,我们仿照火球,创建一个对应的类,基于Projectile

命名为BP_SlingshotRock,意为发射出去的石头

打开蓝图,添加一个静态网格体

设置模型

这里讲一个小技巧,如果你先选中模型

然后回到蓝图中,选择添加,编辑器会智能的推荐你创建对应的组件,并且还会自动给你应用上你选择的模型

我们选择发射组件,可以修改发射物的发射出去的速度,以及是否受重力影响

技能将静态网格体组件的碰撞关闭,我们不需要它的碰撞事件

由于我们在c++里面封装了对应的实现,只需要将GE的实例设置给它即可。最后,我们将创建的此蓝图设置给技能

创建伤害曲线

接下来,就是设置当前技能的伤害,我们需要一条伤害曲线,能够随着敌人的等级提升,提升技能的伤害。所以我们在之前的CT_Damge曲线表格中,增加新的一行,定义远程伤害的曲线。

右键重命名

重命名为Abilities.Ranged

在线上面右键,添加关键帧,用来设置1-40级的技能伤害

我们设置1级伤害7.5,40级伤害35,相对于近战伤害要低,这是正常的,毕竟近战敌人需要靠近玩家才可以攻击

然后我们选中所有关键帧,设置自动,它会自动给我们圆滑曲线

最终效果如下

保存资源,设置到技能,这个技能伤害类型也是物理伤害

应用技能并实现激活技能

技能相关数值我们已经设置完成了,接下来,我们要实现技能应用,并在AI行为树中激活

我们要将技能添加数据资产中,初始化角色时,可以将技能应用到角色ASC身上

打开DA_CharacterClassInfo,将创建的技能设置给远程职业

我们给技能设置技能标签,这个可以用于激活技能

在AI行为树这里,设置对应的标签

攻击目标的黑板键也要设置正确

我们在任务触发执行时,会调用通过标签激活技能

然后测试技能是否能够成功被触发,我们在技能里面连一下测试节点,在技能激活时,绘制一个debg球

接着运行测试效果

创建蒙太奇

接下来,我要实现对蒙太奇的制作,技能激活以后,我们需要敌人去播放一个蒙太奇,来实现攻击动画,然后在攻击中触发发射石头的事件。

首先查看动画是否已经开启了根运动

创建蒙太奇,命名为AM_Attack_Goblin_Slingshot

添加两个事件轨道

在第一个添加MotionWarping旋转事件

配置还是和以前一样

接着在释放攻击的动画位置增加一个通知

标签设置为武器标签,我们想使用武器的节点位置

蒙太奇就制作完成了,我们需要将其数据添加到角色蓝图身上,我们还缺少一项数据,就是使用的武器上的插槽,打开武器骨骼,添加一个插槽,用来设置技能创建的位置

设置完成,我们将动画设置到角色身上

实现技能蓝图逻辑

在技能激活后,我们首先获取到攻击目标,这个是在AI行为树的任务中设置的

在随机获取这一块的节点我们准备整理成c++代码,然后在蓝图中直接调用节点即可

我们在伤害技能基类里面增加一个函数,用于获取一个随机蒙太奇

cpp 复制代码
	//从角色设置的蒙太奇数组总,随机一个蒙太奇使用
	UFUNCTION(BlueprintPure)
	static FTaggedMontage GetRandomTaggedMontageFromArray(const TArray<FTaggedMontage>& TaggedMontages);

使用代码实现就显得结构很整洁

cpp 复制代码
FTaggedMontage URPGDamageGameplayAbility::GetRandomTaggedMontageFromArray(const TArray<FTaggedMontage>& TaggedMontages)
{
	if(TaggedMontages.Num() > 0)
	{
		const int32 RandomNum = FMath::RandRange(0, TaggedMontages.Num() - 1);
		return TaggedMontages[RandomNum];
	}
	return FTaggedMontage();
}

实现完成,编辑代码,我们修改成使用此函数获取随机蒙太奇

然后再添加监听事件节点,监听对应的蒙太奇事件,并从骨骼获取到技能生成的位置

接着,我们测试一下,位置获取的是否正确,方便下一步

运行测试是否能够正常触发

接着,我们修改蓝图,获取攻击目标,然后创建发射物

这样就实现了我们所需的效果,接下来,我们要在投掷物类里面重叠事件回调中,增加逻辑判断,如果是友军,将不会伤害它

相关推荐
唐诺3 小时前
几种广泛使用的 C++ 编译器
c++·编译器
冷眼看人间恩怨4 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
红龙创客4 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin4 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
yuanbenshidiaos5 小时前
c++---------数据类型
java·jvm·c++
十年一梦实验室6 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
taoyong0016 小时前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
这是我586 小时前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
fpcc6 小时前
跟我学c++中级篇——C++中的缓存利用
c++·缓存
呆萌很6 小时前
C++ 集合 list 使用
c++