33. UE5 RPG使用增强输入激活GameplayAbility(三)

在前面的文章,我们实现了使用GameplayTag和InputAction的对应绑定的数据,并且添加到了增强输入映射的上下文中,实现了通过按键打印对应的GameplayTag,这只是我们基础需要制作的。目的主要是为了实现在GameplayAblity上面设置对应的Tag,在按下对应按键时,可以激活技能。
前面的步骤实现了,接下来,我们将在GA的基类上面增加一个GameplayTag配置属性,然后在给角色应用GA时,将GameplayTag设置给GA的实例,在触发InputAction的时候,通过遍历,找到被应用的GA里面有相同的Tag的GA,然后通过代码去触发。

实现

首先,我们需要再技能的基类上增加一个GameplayTag的配置属性,这样,我们就可以在技能蓝图上设置它所使用的GameplayTag了。

public:UPROPERTY(EditDefaultsOnly, Category="Input")FGameplayTag StartupInputTag;

在ASC中实现新的激活事件

接下来,我们要实现在运行时,应用GA时,需要在GamplayAbilitySpec身上将设置的GameplayTag存储下来。
DynamicAbilityTags是一个FGameplayTagContainer类型,它也是可以复制到服务器的,并且在创建GameplayAbilitySpec自动生成。
AbilitySpec.Ability是可以从Spec身上去获取实例的技能基类,并且它也是一个常量对象,我们在其身上设置的参数需要再常量身上去获取。

AbilitySpec.DynamicAbilityTags.AddTag(Cast<UGameplayAbilityBase>(AbilitySpec.Ability)->StartupInputTag);

我们修改ASC中添加技能的函数,它接收的参数是一个技能类的列表,然后遍历,我们在遍历里面通过类去创建Spec实例,如果Spec实例能够转换成我们创建的技能基类对象,那么,我们将基类对象身上设置的Tag设置到DynamicAbilityTags里面。
最后,我们将不会直接激活技能,而是只应用技能,然后通过按键触发技能。

void UAbilitySystemComponentBase::AddCharacterAbilities(const TArray<TSubclassOf<UGameplayAbility>>& StartupAbilities)
{for(const TSubclassOf<UGameplayAbility> AbilityClass : StartupAbilities){FGameplayAbilitySpec AbilitySpec = FGameplayAbilitySpec(AbilityClass, 1);if(const UGameplayAbilityBase* AbilityBase = Cast<UGameplayAbilityBase>(AbilitySpec.Ability)){AbilitySpec.DynamicAbilityTags.AddTag(AbilityBase->StartupInputTag);GiveAbility(AbilitySpec); //只应用不激活// GiveAbilityAndActivateOnce(AbilitySpec); //应用技能并激活一次}}
}

下面,我们将在ASC上面增加两个函数,一个是触发技能的悬停时触发的函数,另一个是触发技能时按键离开时的。这两个函数都需要一个参数Tag去查找需要激活技能。

	void AbilityInputTagHold(const FGameplayTag& InputTag);void AbilityInputTagReleased(const FGameplayTag& InputTag);

在函数实现中,我们首先判断传入的InputTag是否可用

if(!InputTag.IsValid()) return;

然后遍历所有已经应用的技能,GetActivatableAbilities()将返回一个可激活技能的列表

for(auto AbilitySpec : GetActivatableAbilities())

然后我们将对Tag进行比对,判断Spec上设置的Tag和传入的Tag是否相同,如果相同,将对技能处理。

if(AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag))

在技能悬停事件里面,我们首先调用告知GameplayAbility,此技能被触发按下事件,

AbilitySpecInputPressed(AbilitySpec);

防止技能重复被激活,判断当前技能是否处于激活状态

if(!AbilitySpec.IsActive())

尝试激活技能,这里尝试激活,是因为技能激活有很多限制,你调用了激活,只有在符合条件的情况下,才真正被激活。

TryActivateAbility(AbilitySpec.Handle);

而在Released函数内,我们调用了下面函数,告知技能按键事件被抬起。

AbilitySpecInputReleased(AbilitySpec);

这两个事件会触发技能上面的回调,来实现更多的逻辑,我们可以在技能里面覆盖它来实现

	virtual void InputPressed(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) override;virtual void InputReleased(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) override;

下面是在ASC实现的一个激活事件和取消事件的完整代码。

void UAbilitySystemComponentBase::AbilityInputTagHold(const FGameplayTag& InputTag)
{if(!InputTag.IsValid()) return;for(auto AbilitySpec : GetActivatableAbilities()){if(AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag)){AbilitySpecInputPressed(AbilitySpec);if(!AbilitySpec.IsActive()){TryActivateAbility(AbilitySpec.Handle);}}}
}void UAbilitySystemComponentBase::AbilityInputTagReleased(const FGameplayTag& InputTag)
{if(!InputTag.IsValid()) return;for(auto AbilitySpec : GetActivatableAbilities()){if(AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag)){AbilitySpecInputReleased(AbilitySpec);}}
}

在PlayerController中修改并调用ASC的激活事件

接下来,我们将在PlayerController(PC主要储存角色操作的的相关内容的)里,触发操作后,调用ASC身上新创建的函数来触发技能激活。现在,我们还无法在PC身上获取ASC,所以,首先添加一个获取ASC的函数。
我们先创建一个变量存储ASC,然后再增加一个获取ASC的函数。

	UPROPERTY()TObjectPtr<UAbilitySystemComponentBase> AbilitySystemComponentBase;UAbilitySystemComponentBase* GetASC();

然后在函数实现这里,判断ASC是否被设置,如果没有被设置,将通过GAS的函数库去获取,这个静态函数将通过接口去获取

UAbilitySystemComponentBase* APlayerControllerBase::GetASC()
{if(AbilitySystemComponentBase == nullptr){AbilitySystemComponentBase = Cast<UAbilitySystemComponentBase>(UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(GetPawn()));}return AbilitySystemComponentBase;
}

接着,我们修改之前在PC里面触发的事件的函数,之前实现到了打印Tag,现在我们将其修改掉, 不再打印

void APlayerControllerBase::AbilityInputTagPressed(FGameplayTag InputTag)
{GEngine->AddOnScreenDebugMessage(1, 3.f, FColor::Red, *InputTag.ToString());
}void APlayerControllerBase::AbilityInputTagReleased(FGameplayTag InputTag)
{GEngine->AddOnScreenDebugMessage(2, 3.f, FColor::Blue, *InputTag.ToString());
}void APlayerControllerBase::AbilityInputTagHold(FGameplayTag InputTag)
{GEngine->AddOnScreenDebugMessage(3, 3.f, FColor::Yellow, *InputTag.ToString());
}

在函数里,我们需要通过ASC去调用前面实现的激活技能函数,但是我们还无法确保ASC不为空指针,先做一下判断,然后返回。

void APlayerControllerBase::AbilityInputTagPressed(FGameplayTag InputTag)
{// GEngine->AddOnScreenDebugMessage(1, 3.f, FColor::Red, *InputTag.ToString());
}void APlayerControllerBase::AbilityInputTagReleased(FGameplayTag InputTag)
{if(GetASC() == nullptr) return;GetASC()->AbilityInputTagReleased(InputTag);
}void APlayerControllerBase::AbilityInputTagHold(FGameplayTag InputTag)
{if(GetASC() == nullptr) return;GetASC()->AbilityInputTagHold(InputTag);
}

测试

接下来,我们编译代码,解决bug,然后打开UE,找到之前我们做技能测试的蓝图,上面已经可以设置Tag了。
我们设置一个使用鼠标左键触发当前技能
在这里插入图片描述
我们之前测试时,在技能激活时触发ActivateAbility字符串打印,然后在一秒后触发技能关闭,并在屏幕打印技能结束
在这里插入图片描述

编辑运行,正常运行技能将不会被激活,而是在鼠标左键点击时触发
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/796634.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络 实验指导 实验16

实验16 PPP配置实验 1.实验拓扑图 实验10讲了如何添加Se的接口 名称接口IP地址Router1se0/0/0192.168.1.1/24Router0se0/0/0192.168.1.2/24se0/0/1192.168.2.1/24Router2se0/3/0192.168.2.2/24 2.实验目的 &#xff08;1&#xff09;掌握PPP的基本配置步骤和方法 &#xf…

linux之文件系统、inode和动静态库制作和发布

一、背景 1.没有被打开的文件都在磁盘上 --- 磁盘级文件 2.对磁盘级别的文件&#xff0c;我们的侧重点 单个文件角度 -- 这个文件在哪里&#xff0c;有多大&#xff0c;其他属性是什么&#xff1f; 站在系统角度 -- 一共有多少文件&#xff1f;各自属性在哪里&#xff1f…

Hive 之 UDF 运用(包会的)

文章目录 UDF 是什么&#xff1f;reflect静态方法调用实例方法调用 自定义 UDF&#xff08;GenericUDF&#xff09;1.创建项目2.创建类继承 UDF3.数据类型判断4.编写业务逻辑5.定义函数描述信息6.打包与上传7.注册 UDF 函数并测试返回复杂的数据类型 UDF 是什么&#xff1f; H…

数组-二维数组

本笔记为47 数组-二维数组定义方式_哔哩哔哩_bilibili的学习笔记 二维数组 定义方式 注&#xff1a; 常用第二种方式定义&#xff0c;原因&#xff1a;第二种方式更清晰列数可以省行数不可省 &#xff0c;详见上述第四种定义方式 示例&#xff1a; 二维数组 数组名 作用&am…

【QT+QGIS跨平台编译】063:【qca-logger+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

点击查看专栏目录 文章目录 一、qca-logger插件介绍二、QCA下载三、文件分析四、pro文件五、编译实践5.1 windows下编译5.2 linux下编译5.3 macos下编译一、qca-logger插件介绍 QCA::Logger 是 Qt Cryptographic Architecture (QCA) 库中的一个类,它提供了一个简单而灵活的日志…

PostgrerSQL基本使用与数据备份

前言 上篇了解了 PostgrerSQL 数据库的部署PostgreSQL关系型数据库介绍与部署-CSDN博客&#xff0c;本篇将继续就其基本操作、备份与还原内容做相关介绍。 目录 一、数据库的操作 1. 本机登录 2. 开启远程登录 2.1 开放远程端口 2.2 编辑配置文件 2.3 修改配置密码 2.…

xss.pwnfunction-Ma Spaghet!

根据代码得知 这个是根据get传参的并且是由someboby来接收参数的 所以 <script>alert(1137)</script> js并没有执行因为 HTML5中指定不执行由innerHTML插入的<script>标签 所以 ?somebody<img%20src1%20onerror"alert(1337)"> 这样就成…

PowerJob 分布式任务调度简介

目录 适用场景 设计目标 PowerJob 功能全景 任务调度 工作流 分布式计算 动态容器 什么是动态容器? 使用场景 可维护性和灵活性的完美结合 实时日志&在线运维 PowerJob 系统组件 PowerJob 应用场景 PowerJob 的优势 PowerJob&#xff08;原OhMyScheduler&…

Pytorch数据结构:GPU加速

文章目录 一、GPU加速1. 检查GPU可用性&#xff1a;2. GPU不可用需要具体查看问题3. 指定设备4.将张量和模型转移到GPU5.执行计算&#xff1a;6.将结果转移回CPU 二、转移原理1. 数据和模型的存储2. 数据传输3. 计算执行4. 设备管理5.小结 三、to方法的参数类型 一、GPU加速 .…

瑞_Redis_商户查询缓存_添加Redis缓存缓存更新策略

文章目录 项目介绍1 短信登录2 商户查询缓存2.1 什么是缓存2.1.1 缓存的应用场景2.1.2 为什么要使用缓存2.1.3 Web应用中缓存的作用2.1.4 Web应用中缓存的成本 2.2 添加Redis缓存2.2.1 背景2.2.2 缓存模型和思路2.2.3 代码实现2.2.4 测试附&#xff1a;IDEA控制台输出自动换行设…

【动态规划】【01背包】Leetcode 416. 分割等和子集

【动态规划】【01背包】Leetcode 416. 分割等和子集 ---------------&#x1f388;&#x1f388;416. 分割等和子集 题目链接&#x1f388;&#x1f388;------------------- 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0…

竞赛 交通目标检测-行人车辆检测流量计数 - 竞赛

文章目录 0 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…

Python3 Ubuntu

一、安装中文输入法 1.sudo apt install ibus-sunpinyin 2.点击右上角输入法&#xff0c;然后点击加号&#xff0c;输入yin添加进来&#xff0c;最后选中输入法即可 二、安装截屏软件 1.sudo apt install gnome-screenshot 三、安装opencv-python 1.pip3 install --upgrade…

HTTP协议报文的结构的补充和from表单以及ajax表单

响应 状态码 表示了这次请求对应的响应,是什么样的状态(成功,失败,还是其他的情况.还有及其对应的原因&#xff09; 主要有这些类 成功状态码&#xff1a;其中200最常见&#xff0c;表示成功 重定向状态码&#xff1a;很多时候,页面跳转,就可以通过重定向来实现. 还有的时…

智慧牧场数据 7

1 体征数据采集 需求:获取奶牛记步信息 三轴加速度测量&#xff1a;加速度测量计反应的加速向量与当前的受力方向是相反&#xff0c;单位为g 陀螺仪&#xff0c;是用来测量角速度的&#xff0c;单位为度每秒&#xff08;deg/s&#xff09; 2000deg/s 相当于1秒钟多少转 1.1…

小米汽车su7全色系展示源码

源码简介 小米汽车全色系展示源码&#xff0c;小米汽车su7全色系展示源码 安装教程 纯HTML&#xff0c;直接将压缩包上传网站目录解压即可 首页截图 源码下载 小米汽车su7全色系展示源码-小8源码屋源码简介 小米汽车全色系展示源码&#xff0c;小米汽车su7全色系展示源码 …

如何不编程用 ChatGPT 爬取网站数据?

敢于大胆设想&#xff0c;才能在 AI 时代提出好问题。 需求 很多小伙伴&#xff0c;都需要为研究获取数据。从网上爬取数据&#xff0c;是其中关键一环。以往&#xff0c;这都需要编程来实现。 可最近&#xff0c;一位星友在知识星球提问&#xff1a; 这里涉及到一些个人隐私&a…

Redission--布隆过滤器解决缓存穿透问题

布隆过滤器在缓存穿透问题中的使用 布隆过滤器的核心是一个位数组 布隆过滤器的误判 使用Redission的布隆过滤器步骤 添加 Redission 依赖&#xff1a;首先需要将 Redission 添加到你的 Java 项目中&#xff0c;你可以通过 Maven 来添加 Redission 的依赖。 创建 Redissio…

深度学习相关知识

一.环境配置 1.cuda/cudnn安装&#xff1a; 安装cuda之前首先安装vs&#xff0c;vs版本从低到高安装。 a) 安装cuda&#xff1a;首先查看显卡支持的最高CUDA的版本&#xff0c;以便下载对应的CUDA安装包&#xff1b; cmd命令行&#xff1a;nvidia-smi,显示如下&#xff1a;…

【单片机】CJSH22-CH2O,甲醛传感器,甲醛传感器数据读取处理

原理图 解析程序 逻辑是&#xff1a; 1、初始化串口和定时器10ms中断 2、循环读取一帧数据到rev_CH2O_bufferdata 3、在主函数解析数据rev_CH2O_bufferdata 4、最终的pm2.5数值就是CH2O_value 使用CH2O_value的数据即可。 PPB单位&#xff0c;除以1000就是ppm&#xff0c;再…