前面,我们实现了敌人的近战普通攻击,还兼容了对于没有武器的敌人的攻击。有近战就要有远程,这一篇,我们实现一下敌人的远程攻击。
首先,由于创建的资源增多,我们将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();
}
实现完成,编辑代码,我们修改成使用此函数获取随机蒙太奇
然后再添加监听事件节点,监听对应的蒙太奇事件,并从骨骼获取到技能生成的位置
接着,我们测试一下,位置获取的是否正确,方便下一步
运行测试是否能够正常触发
接着,我们修改蓝图,获取攻击目标,然后创建发射物
这样就实现了我们所需的效果,接下来,我们要在投掷物类里面重叠事件回调中,增加逻辑判断,如果是友军,将不会伤害它