61. UE5 RPG 实现敌人近战攻击技能和转向攻击

2024-06-01 14:12

本文主要是介绍61. UE5 RPG 实现敌人近战攻击技能和转向攻击,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在前面,我们实现了敌人的AI系统,敌人可以根据自身的职业进行匹配对应的攻击方式。比如近战战士会靠近目标后进行攻击然后躲避目标的攻击接着进行攻击。我们实现了敌人的AI行为,但是现在还没有实现需要释放的技能,接下来,我们将实现敌人的使用的技能,刚好回顾一下之前的实现的功能。

首先基于之前的伤害技能基类,创建一个近战技能基类
在这里插入图片描述
命名为近战技能 RPGMeleeAbility
在这里插入图片描述
我们要实现技能的激活,需要使用到GameplayTag,所以我们增加一个新的技能标签用于激活。
在RPGGameplayTags.h增加新的标签

FGameplayTag Abilities_Attack; //攻击技能激活标签

然后将标签添加到标签管理器

	/** Abilities*/GameplayTags.Abilities_Attack = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Abilities.Attack"),FString("攻击技能标签"));

接下来,我们要实现在角色数据表里面配置它的技能,打开Character Class Info.h增加对应的属性设置

//对应每个职业的属性和技能
USTRUCT()
struct FCharacterClassDefaultInfo
{GENERATED_BODY()UPROPERTY(EditDefaultsOnly, Category="Class Defaults")TSubclassOf<UGameplayEffect> PrimaryAttributes;UPROPERTY(EditDefaultsOnly, Category="Class Defaults")TArray<TSubclassOf<UGameplayAbility>> StartupAbilities;
};

后面在UE的蓝图里面设置以后,我们可以在结构体内获取需要应用的技能。接下来,我们还需要回忆一下如何应用敌人的技能的,我们是在敌人的基类里面,去实现的技能的应用,
在这里插入图片描述
我们要扩展这个函数,增加传入角色的类型,通过类型去获取特定职业的技能。

	//初始化角色的技能UFUNCTION(BlueprintCallable, Category="MyAbilitySystemLibrary|CharacterClassDefaults")static void GiveStartupAbilities(const UObject* WorldContextObject, UAbilitySystemComponent* ASC, ECharacterClass CharacterClass);

扩展函数,从数据结构中获取到数据并应用到角色的ASC上

void URPGAbilitySystemBlueprintLibrary::GiveStartupAbilities(const UObject* WorldContextObject, UAbilitySystemComponent* ASC, ECharacterClass CharacterClass)
{//从实例获取到关卡角色的配置UCharacterClassInfo* CharacterClassInfo = GetCharacterClassInfo(WorldContextObject);if(CharacterClassInfo == nullptr) return;//从战斗接口获取到角色的等级ICombatInterface* CombatInterface = Cast<ICombatInterface>(ASC->GetAvatarActor());int32 CharacterLevel = 1;if(CombatInterface){CharacterLevel = CombatInterface->GetPlayerLevel();}//应用角色拥有的技能数组for(const TSubclassOf<UGameplayAbility> AbilityClass : CharacterClassInfo->CommonAbilities){FGameplayAbilitySpec AbilitySpec = FGameplayAbilitySpec(AbilityClass, CharacterLevel); //创建技能实例ASC->GiveAbility(AbilitySpec); //只应用不激活}//获取到默认的基础角色数据const FCharacterClassDefaultInfo ClassDefaultInfo = CharacterClassInfo->GetClassDefaultInfo(CharacterClass);//应用职业技能数组for(const TSubclassOf<UGameplayAbility> AbilityClass : ClassDefaultInfo.StartupAbilities){FGameplayAbilitySpec AbilitySpec = FGameplayAbilitySpec(AbilityClass, CharacterLevel); //创建技能实例ASC->GiveAbility(AbilitySpec); //只应用不激活}
}

敌人的角色类型也是设置在敌人基类上的,所以我们可以直接调用时传入

	//初始化角色的技能if(HasAuthority()){URPGAbilitySystemBlueprintLibrary::GiveStartupAbilities(this, AbilitySystemComponent, CharacterClass);}

在UE中设置

接着我们可以编译代码打开UE,在UE里面创建一个对应的蓝图类
在这里插入图片描述
命名为GA_GoblinSpearAttack
在这里插入图片描述
首先设置技能标签,我们就可以通过标签激活技能。
在这里插入图片描述
在技能里实现测试代码,在触发技能时,绘制一个绿色的球
在这里插入图片描述
接着打开我们的数据表,现在每个职业多了一个需要设置的技能数组,将我们创建的技能添加给战士
在这里插入图片描述
攻击是由AI触发的,所以,我们在AI的攻击任务中,通过标签激活技能即可。我们从控制的pawn中获取到ASC,然后通过标签激活技能
在这里插入图片描述
创建的变量我们可以将其设置外部可以设置
在这里插入图片描述
然后再行为树中设置激活的技能标签
在这里插入图片描述
接着运行测试效果,如果允许哥布林在攻击时绘制绿色的球,证明我们技能激活成功。
在这里插入图片描述

设置技能攻击蒙太奇

回忆一下之前我们实现的火球术,需要使用一个蒙太奇动画,然后在蒙太奇动画中触发事件发射火球实现技能的释放。接下来,我们使用同样的思路实现近战攻击的技能。
找到敌人的攻击动画,创建一个蒙太奇
在这里插入图片描述
创建名称AM_Attack_GoblinSpear,方便在蒙太奇下拉中选择
在这里插入图片描述
在蒙太奇中,我们需要增加MotionWarping来控制朝向,注意,动画必须要支持根动画
在这里插入图片描述
设置角色在蓄力的时候转向
在这里插入图片描述
设置触发名称,关闭移动,只留下转向,切换转向类型为朝向目标
在这里插入图片描述
我们有了蒙太奇,还需要实现在攻击时朝向攻击目标,按照之前的实现方式,我们通过MotionWarpping插件实现转向。

添加转向插件

我们需要在敌人基类身上增加MotionWarpping插件
在这里插入图片描述
实现调用,和主角的一样即可,其实这里我们可以实现一个角色基类蓝图,在里面设置一些通用的函数,这里先不改。
在这里插入图片描述
要实现这个功能,我们需要让敌人知道攻击目标的位置,然后攻击时朝向它,我们需要在AI控制器中获取到目标。
我们在敌人接口里增加两个函数,用于设置和获取攻击目标,这里设置了BlueprintNativeEvent,它默认给我们实现,并且可以在蓝图中实现此函数,如果在蓝图中实现了此函数,在蓝图中调用,将使用蓝图的版本。

	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)void SetCombatTarget(AActor* InCombatTarget); //设置敌人的攻击目标UFUNCTION(BlueprintCallable, BlueprintNativeEvent)AActor* GetCombatTarget() const; //获取敌人的攻击目标

接下来我们在敌人基类里面覆写这两个函数,并去实现,这样写法是因为我们是通过UE让蓝图去实现的此函数,所以我们需要加上Vitrual和后面的_Implementation

	/* IEnemyInterface敌人接口 */virtual void HighlightActor() override; //高亮virtual void UnHighlightActor() override; //取消高亮virtual AActor* GetCombatTarget_Implementation() const override;virtual void SetCombatTarget_Implementation(AActor* InCombatTarget) override;/* IEnemyInterface敌人接口 结束 */

在cpp中实现这两个函数,我们也可以在蓝图中实现,这里看个人喜好

AActor* ARPGEnemy::GetCombatTarget_Implementation() const
{return CombatTarget;
}void ARPGEnemy::SetCombatTarget_Implementation(AActor* InCombatTarget)
{CombatTarget = InCombatTarget;
}

有了设置攻击目标的函数,我们在AI攻击任务里面就可以设置攻击对象了。
在任务里增加一个黑板键选择器,用于在AI行为树中设置绑定的黑板键
在这里插入图片描述
在AI行为树中设置攻击目标为跟随目标黑板键
在这里插入图片描述
这样我们就可以在任务里面获取攻击目标,并设置给控制的Pawn身上
在这里插入图片描述
接下来,我们在技能里面,从角色身上获取到攻击目标,然后转换为战斗接口,调用偏转朝向的函数,将朝向位置设置,然后再调用蒙太奇播放动画
在这里插入图片描述
接着允许查看效果,是否真的能捅向目标
在这里插入图片描述

添加攻击事件

接下来,我们需要在蒙太奇动画里,攻击的那一刻,触发一个事件,来告诉技能当前可以计算攻击。就像之前实现火球术时的一样。
在这里插入图片描述
由于我们没有设置对应的通知,我们去标签管理器增加一个近战攻击的通知标签。由于这个标签不需要在c++内使用,所以我们可以直接通过UE添加。
在这里插入图片描述
设置属于攻击的近战攻击标签
在这里插入图片描述
设置完成,打开蒙太奇,设置到通知上面,这样就可以在技能里面去接收对应的标签通知了。
在这里插入图片描述
然后我们在技能中设置等待游戏事件即可,Only Match Exact是标签必须全部匹配才可以触发事件
在这里插入图片描述
现在我们接收到事件了,还需要考虑如何触发攻击。在之前实现火球从法杖杖尖处释放时,我们在战斗接口设置了一个获取技能释放位置的函数,所以我们可以通过获取到设置的位置,生成一个碰撞球体,判断是否和目标产生重叠实现攻击并应用GE。
在这里插入图片描述
但是当前函数无法在蓝图中调用,所以,我们需要修改它,将其变成可以在蓝图中调用的版本

	//获取技能释放位置,通过在蓝图中设置获取WeaponTipSocketName的位置UFUNCTION(BlueprintNativeEvent, BlueprintCallable)FVector GetCombatSocketLocation() const;

并将cpp的实现删除。

在角色基类修改它的继承,修改成GetCombatSocketLocation_Implementation

virtual FVector GetCombatSocketLocation_Implementation() const override;

并将实现代码函数名称也修改掉

FVector ARPGCharacter::GetCombatSocketLocation_Implementation() const
{return Weapon->GetSocketLocation(WeaponTipSocketName);
}

完成以后,就可以编译打开UE,并设置它的WeaponTipSocketName
在这里插入图片描述
这里名称,我们可以在武器骨骼上面增加插槽实现
在这里插入图片描述
接着在技能蓝图里,我们首先实现接收到事件后绘制一个调试球体,来表现攻击范围
在这里插入图片描述
运行查看释放能够正确绘制出调试球体
在这里插入图片描述
我们在点击实现角色攻击时,发现一个问题,有个地方报错了,提示我们不要在接口中直接调用Event函数。而是调用Execute_GetCombatSocketLocation。
在这里插入图片描述
往前定位发现是在调用,直接调用获取位置,由于前面我们将其修改成了蓝图编译生成函数,所以在C++里面不能够直接调用
在这里插入图片描述
所以我们修改此行代码为使用Execute_GetCombatSocketLocation调用

const FVector SocketLocation = ICombatInterface::Execute_GetCombatSocketLocation(GetAvatarActorFromActorInfo());

接着运行测试就行了。

这篇关于61. UE5 RPG 实现敌人近战攻击技能和转向攻击的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1021237

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2