32. UE5 RPG使用增强输入激活GameplayAbility(二)

在上一篇文章中,我们实现了Tag和InputAction的数据对应,后面,我们会通过InputAction触发对应的Tag,然后在GameplayAbility身上设置对应的Tag,然后通过Tag遍历角色身上的所有应用的技能去激活。为了实现这个功能,我们需要增加自定义输入控件,通过此控件增加函数实现输入触发对应Tag触发,数据已经有了,这一篇的内容为创建一个用于增加自定义绑定事件的Component,以及在PlayerController上面使用新的绑定事件。

查看源代码中的绑定

在之前,我们实现了绑定wasd键位,实现了角色的移动功能,使用的是一个Action绑定的事件,然后触发移动事件,我们独立计算出角色移动的法向并设置移动。
在设置输入函数中,我们获取到了增强输入组件,然后通过增强输入的组件去实现的Action触发自定义的移动函数去计算。

void APlayerControllerBase::SetupInputComponent()
{Super::SetupInputComponent();UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(InputComponent); //获取到增强输入组件EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &APlayerControllerBase::Move); //绑定移动事件
}

我们查看源码
在这里插入图片描述
我们发现它还有一个模版式的绑定方法,无需直接定义准确格式,只需要定义基础格式即可
在这里插入图片描述
我们在实现自定义绑定时,需要实现多种绑定,所以接下来,我们也使用这种方式去实现。

创建EnhancedInputComponent

接下来,我们将创建一个基于EnhancedInputComponent的类,来替换掉默认的EnhancedInputComponent类,然后可以从PlayerController里调用它的自定义函数。
首先添加c++类,选择EnhancedInputComponent
在这里插入图片描述
命个名,这个取名InputComponentBase
在这里插入图片描述
打开编辑器,在类里面,添加一个公共函数,用于绑定技能的InputAction,我们这里使用模版函数,模板函数允许用户为特定的类型实例化该函数。定义的时候不需要固定参数的确定类型,只需要确定基础类型即可。
在参数这里,我们可以将整个DataAsset传入,然后遍历整个参数列表,进行事件绑定

public:template<class UserClass, typename PressedFuncType, typename ReleasedFuncType, typename HoldFuncType>void BindAbilityAction(const UInputConfig* InputConfig, UserClass* Object, PressedFuncType PressedFunc, ReleasedFuncType ReleasedFunc, HoldFuncType HoldFunc);

在函数实现这里,我们首先判断InputConfig是否设置,没有设置将直接触发断点

check(InputConfig);

然后遍历AbilityInputActions这个变量,这个变量是我们在面板设置了数据列表的变量

for(const FInputActionStruct& Action : InputConfig->AbilityInputActions)

然后判断,每个参数,如果InputAction和InputTag都有效,才可以进行下一步

if(Action.InputAction && Action.InputTag.IsValid())

然后就是判断函数是否设置,设置后,就可以进行绑定
BindAction函数参数分别是InputAction,触发事件的阶段,对象,触发的事件,(如果需要传参数,后面将参数传入,回调函数实现那里也需要设置对应类型的参数获取才可以)

if(PressedFunc)
{BindAction(Action.InputAction, ETriggerEvent::Started, Object, PressedFunc, Action.InputTag);
}

可以触发的事件设置这里,查看内部定义,是一个枚举,所以我们需要通过::获取,每个参数的意义:

  • None 不会触发
  • Triggered 将在每一帧触发
  • Started 在事件开始时触发,Triggered也可能在同一帧触发,但是Started会在它之前触发
  • Ongoing 操作正在进行,但是还没到某个设置的阈值的阶段,可以定义为正在进行,还未完成
  • Canceled 可以定义为Ongoing 的事件在还未完成时取消了操作
  • Completed 从Triggered 状态转换为None时触发,或者Ongoing 状态完成时触发
/**
* Trigger events are the Action's interpretation of all Trigger State transitions that occurred for the action in the last tick
*/
UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
enum class ETriggerEvent : uint8
{// No significant trigger state changes occurred and there are no active device inputsNone		= (0x0)		UMETA(Hidden),// Triggering occurred after one or more processing ticksTriggered	= (1 << 0),	// ETriggerState (None -> Triggered, Ongoing -> Triggered, Triggered -> Triggered)// An event has occurred that has begun Trigger evaluation. Note: Triggered may also occur this frame, but this event will always be fired first.Started		= (1 << 1),	// ETriggerState (None -> Ongoing, None -> Triggered)// Triggering is still being processed. For example, an action with a "Press and Hold" trigger// will be "Ongoing" while the user is holding down the key but the time threshold has not been met yet. Ongoing		= (1 << 2),	// ETriggerState (Ongoing -> Ongoing)// Triggering has been canceled. For example,  the user has let go of a key before the "Press and Hold" time threshold.// The action has started to be evaluated, but never completed. Canceled	= (1 << 3),	// ETriggerState (Ongoing -> None)// The trigger state has transitioned from Triggered to None this frame, i.e. Triggering has finished.// Note: Using this event restricts you to one set of triggers for Started/Completed events. You may prefer two actions, each with its own trigger rules.// Completed will not fire if any trigger reports Ongoing on the same frame, but both should fire. e.g. Tick 2 of Hold (= Ongoing) + Pressed (= None) combo will raise Ongoing event only.Completed	= (1 << 4),	// ETriggerState (Triggered -> None)
};
ENUM_CLASS_FLAGS(ETriggerEvent)

下面就是我们完成的整个函数定义的实现代码。

template <class UserClass, typename PressedFuncType, typename ReleasedFuncType, typename HoldFuncType>
void UInputComponentBase::BindAbilityAction(const UInputConfig* InputConfig, UserClass* Object,PressedFuncType PressedFunc, ReleasedFuncType ReleasedFunc, HoldFuncType HoldFunc)
{check(InputConfig);for(const FInputActionStruct& Action : InputConfig->AbilityInputActions){if(Action.InputAction && Action.InputTag.IsValid()){if(PressedFunc){BindAction(Action.InputAction, ETriggerEvent::Started, Object, PressedFunc, Action.InputTag);}if(HoldFunc){BindAction(Action.InputAction, ETriggerEvent::Triggered, Object, HoldFunc, Action.InputTag);}if(ReleasedFunc){BindAction(Action.InputAction, ETriggerEvent::Completed, Object, ReleasedFunc, Action.InputTag);}}}
}

在PlayerController中使用

上面,我们实现了自定义的绑定函数,可以绑定三种状态下的回调事件的函数:按下,悬停,抬起。
接下来,我们将在PlayerController里面使用并实现对Action的绑定,首先,我们需要一个变量,可以在UE里设置使用InputConfig,这样,也方便我们切换数据

	UPROPERTY(EditDefaultsOnly, Category="Input")TObjectPtr<UInputConfig> InputConfig;

然后增加三个函数,用于绑定到事件中

	void AbilityInputTagPressed(FGameplayTag InputTag);void AbilityInputTagReleased(FGameplayTag InputTag);void AbilityInputTagHold(FGameplayTag InputTag);

在函数实现里面,我先做测试性的打印,使用GEngine->AddOnScreenDebugMessage(Key, TimeToDisplay, Color, String)函数,它的参数为:

  • key 作为打印的标示,如果设置为-1,将正常显示,如果设置一个大于0的整数,每次打印将替换之前相同key的打印
  • TimeToDisplay 在运行时的显示时间
  • Color 打印时使用的颜色
  • String 打印的内容
GEngine->AddOnScreenDebugMessage(1, 3.f, FColor::Red, *InputTag.ToString());

我们将其不同的事件打印的内容也作区分,键位按下时红色,抬起时蓝色,按住时黄色

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());
}

最后,我们将修改输入设置,将类型转换为我们创建的自定义组件类型,然后调用之前写好的自定义绑定函数。这里的&ThisClass::指定引用当前类里面的成员函数,也可以和绑定Move时一样写类名称

void APlayerControllerBase::SetupInputComponent()
{Super::SetupInputComponent();UInputComponentBase* EnhancedInputComponent = CastChecked<UInputComponentBase>(InputComponent); //获取到增强输入组件EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &APlayerControllerBase::Move); //绑定移动事件EnhancedInputComponent->BindAbilityAction(InputConfig, this, &ThisClass::AbilityInputTagPressed,&ThisClass::AbilityInputTagReleased, &ThisClass::AbilityInputTagHold);
}

测试输入绑定

运行UE,打开项目设置,在输入一项中,找到默认类这一项,上面会有两项,默认输入类,默认输入组件类
在这里插入图片描述
将第二项修改为我们自定义的输入组件类
在这里插入图片描述
接着打开PlayerController蓝图,发现多了InputConfig一项
在这里插入图片描述
在这里,将我们上一篇文章中创建的InputConfig数据设置上
在这里插入图片描述
接着就可以运行了,然后测试我们添加的那六个tag标签是否都可以打印出来(鼠标左右键+数字1234)
首先鼠标左键按住,会将Pressed和hold打印出来
在这里插入图片描述
按住不松手三秒,会发现hold事件还在
在这里插入图片描述
松手事,会触发Released事件
在这里插入图片描述
我们这样可以多测试几次,查看是否都没有问题
在这里插入图片描述

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

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

相关文章

精读 Generating Mammography Reports from Multi-view Mammograms with BERT

精读&#xff08;非常推荐&#xff09; Generating Mammography Reports from Multi-view Mammograms with BERT&#xff08;上&#xff09; 这里的作者有个叫 Ilya 的吓坏我了 1. Abstract Writing mammography reports can be errorprone and time-consuming for radiolog…

基于单片机的数字万用表设计

**单片机设计介绍&#xff0c;基于单片机的数字万用表设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的数字万用表设计概要是关于使用单片机技术来实现数字万用表功能的一种设计方案。下面将详细概述该设计的各个…

【性能测试】接口测试各知识第2篇:学习目标,1. 理解接口的概念【附代码文档】

接口测试完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;接口测试&#xff0c;学习目标学习目标,2. 接口测试课程大纲,3. 接口学完样品,4. 学完课程,学到什么,5. 参考:,1. 理解接口的概念。学习目标&#xff0c;RESTFUL1. 理解接口的概念,2.什么是接口测试…

ChatGPT 的行家指南

原文&#xff1a;An Insider’s Guide to using ChatGPT 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 介绍 你是否厌倦了花费无数小时为你的业务创建内容&#xff1f;从博客文章到社交媒体更新&#xff0c;从电子书内容到电子邮件&#xff0c;这可能是一个耗时的过…

如何保持数据一致性

如何保持数据一致性 数据库和缓存&#xff08;比如&#xff1a;redis&#xff09;双写数据一致性问题&#xff0c;是一个跟开发语言无关的公共问题。尤其在高并发的场景下&#xff0c;这个问题变得更加严重。 问题描述&#xff1a; 1.在高并发的场景中&#xff0c;针对同一个…

基于java+SpringBoot+Vue的学生心理咨询评估系统设计与实现

基于javaSpringBootVue的学生心理咨询评估系统设计与实现 开发语言: Java 数据库: MySQL技术: Spring Boot MyBatis工具: IDEA/Eclipse、Navicat、Maven 系统展示 后台展示 用户管理模块&#xff1a;管理员可以查看、添加、编辑和删除用户信息。 试题管理模块&#xff1a…

Qt + VS2017 创建一个简单的图片加载应用程序

简介&#xff1a; 本文介绍了如何使用Qt创建一个简单的图片加载应用程序。该应用程序可以打开图片文件并在界面上显示选定的图片&#xff0c;并保存用户上次选择的图片路径。 1. 创建项目&#xff1a; 首先&#xff0c;在VS中创建一个新的Qt Widgets应用程序项目&#xff0c;并…

LeetCode 1379.找出克隆二叉树中的相同节点:二叉树遍历

【LetMeFly】1379.找出克隆二叉树中的相同节点&#xff1a;二叉树遍历 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-a-corresponding-node-of-a-binary-tree-in-a-clone-of-that-tree/ 给你两棵二叉树&#xff0c;原始树 original 和克隆树 cloned&#xff0…

Golang | Leetcode Golang题解之第3题无重复字符的最长子串

题目&#xff1a; 题解&#xff1a; func lengthOfLongestSubstring(s string) int {// 哈希集合&#xff0c;记录每个字符是否出现过m : map[byte]int{}n : len(s)// 右指针&#xff0c;初始值为 -1&#xff0c;相当于我们在字符串的左边界的左侧&#xff0c;还没有开始移动r…

CMD 命令行进入到电脑硬盘的某个目录的几种方式

本文介绍几种 cmd 命令行进入到电脑硬盘的某个目录的几种方式。 1、在具体文件目录地址栏输入 cmd 回车 这是最快的、最牛的方式&#xff0c;没有之一。 比如&#xff1a;我想进入一个层级很深的文件目录&#xff0c;直接打开在那个目录&#xff0c;把地址栏信息删除清空&am…

FLink学习(三)-DataStream

一、DataStream 1&#xff0c;支持序列化的类型有 基本类型&#xff0c;即 String、Long、Integer、Boolean、Array复合类型&#xff1a;Tuples、POJOs 和 Scala case classes Tuples Flink 自带有 Tuple0 到 Tuple25 类型 Tuple2<String, Integer> person Tuple2.…

【C++进阶】带你手撕红黑树(红与黑的爱恨厮杀)

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;c大冒险 总有光环在陨落&#xff0c;总有新星在闪烁 引言&#xff1a; 之前我们…

vivado 串行矢量格式 (SVF) 文件编程

串行矢量格式 (SVF) 文件编程 注释 &#xff1a; 串行矢量格式 (SVF) 编程在 Versal ™ 器件上不受支持。 对 FPGA 和配置存储器器件进行编程的另一种方法是通过使用串行矢量格式 (SVF) 文件来执行编程。通过 Vivado Design Suite 和 Vivado Lab Edition 生成的 SVF …

八数码(bfs做法)非常详细,适合新手服用

题目描述&#xff1a; 在一个 33 的网格中&#xff0c;1∼8这 8 个数字和一个 x 恰好不重不漏地分布在这 33 的网格中。 例如&#xff1a; 1 2 3 x 4 6 7 5 8在游戏过程中&#xff0c;可以把 x 与其上、下、左、右四个方向之一的数字交换&#xff08;如果存在&#xff09;。 我…

JS-11A/11时间继电器 板前接线 JOSEF约瑟

系列型号&#xff1a; JS-11A/11集成电路时间继电器&#xff1b;JS-11A/12集成电路时间继电器&#xff1b; JS-11A/13集成电路时间继电器&#xff1b;JS-11A/136集成电路时间继电器&#xff1b; JS-11A/137集成电路时间继电器&#xff1b;JS-11A/22集成电路时间继电器&#…

Folder Icons for Mac v1.8 激活版文件夹个性化图标修改软件

Folder Icons for Mac是一款Mac OS平台上的文件夹图标修改软件&#xff0c;同时也是一款非常有意思的系统美化软件。这款软件的主要功能是可以将Mac的默认文件夹图标更改为非常漂亮有趣的个性化图标。 软件下载&#xff1a;Folder Icons for Mac v1.8 激活版 以下是这款软件的一…

亚马逊自动养号软件新手必读:养号过程中的关键注意事项

亚马逊买家号想要养号效果好&#xff0c;需要重点注意以下4点: 1、前期的准备工作:确保账号登陆的环境是安全的&#xff0c;最好就是用的家庭IP。然后是FBA收货 地址&#xff0c;固定的收货地址有利于账号的安全稳定性&#xff0c;还有一个就是确定安全的成交付款方式&#xf…

网络协议栈--数据链路层

目录 对比理解“数据链路层”和“网络层”一、认识以太网1.1 以太网帧格式1.2 认识MAC地址1.3 对比理解MAC地址和IP地址1.4 认识MTU1.5 MTU对IP协议的影响1.6 MTU对UDP协议的影响1.7 MTU对于TCP协议的影响1.8 查看硬件地址和MTU 二、ARP协议2.1 ARP协议的作用2.2 ARP协议的工作…

Springboot传参要求

传参的参数名称必须与Set方法的参数名字相同 &#xff0c;不然会报错。

MacBook安装使用XMind

MacBook安装使用XMind XMind简介 官方地址: https://www.xmind.cn/ XMind 是一个全功能的思维导图和头脑风暴软件,为激发灵感和创意而生。作为一款有效提升工作和生活效率的生产力工具,受到全球百千万用户的青睐。 XMind 是一款非常实用的商业思维导图软件&#xff0c;应用…