91. UE5 RPG 实现拖拽装配技能以及解除委托的绑定

news2024/11/25 13:00:36

在上一篇文章里,实现了通过选中技能,然后点击下方的装备技能插槽实现了技能的装配。为了丰富技能装配功能,在这一篇里,我们实现一下通过拖拽技能,实现拖拽功能,我们需要修改两个用户控件,一个就是技能按钮,我们需要在里面增加拖拽的功能,并且不能够与点击事件产生冲突,然后我们还需要在装配插槽增加拖拽放入的事件处理,在拖入技能装配插槽后,处理对应的逻辑。

具体操作流程,在拖拽技能时,技能能够根据装配的插槽来修改大小(主动技能插槽比被动技能插槽大),如果当前技能没有处于焦点,我们在拖拽时,会自动将其设置为焦点状态,然后触发拖拽后,可以装配的位置会高亮显示,当将技能拖拽到可放入的槽位时,拖拽的技能也会高亮,松手后,技能将应用到目标槽位,实现就用上一篇文章里的点击装配即可。

实现拖拽时对应装配部位可以高亮显示

首先,我们实现拖拽,可装配的槽位高亮显示,增加一个新的委托类型

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FWaitForEquipSelectionSignature, const FGameplayTag&, InputTag, const FGameplayTag&, AbilityType); //等待技能装备选择

然后在技能面板控制器增加一个新的委托变量,用于装配栏监听

	UPROPERTY(BlueprintAssignable)
	FWaitForEquipSelectionSignature WaitForEquipSignature; //拖拽选中技能按钮后,广播可拖拽位置高亮显示

然后我们增加两个函数,用于在拖拽开始时调用,和在拖拽结束时调用

	UFUNCTION(BlueprintCallable)
	void EquipDragStart(); //装配技能按钮按下事件

	UFUNCTION(BlueprintCallable)
	void EquipDragEnd(); //装配技能按钮按下事件

这两个函数,主要用于广播委托,我们可以在蓝图里监听委托,根据委托设置是否需要显示隐藏高亮效果,委托广播的是输入标签和技能类型,在设置高亮时,我们可以根据这两个值来判断当前是否需要设置高亮

void USpellMenuWidgetController::EquipDragStart()
{
	const FRPGAbilityInfo Info = AbilityInfo->FindAbilityInfoForTag(SelectedAbility.Ability);
	const FGameplayTag& SelectedAbilityInputTag = GetRPGASC()->GetInputTagFromAbilityTag(SelectedAbility.Ability);
	WaitForEquipSignature.Broadcast(SelectedAbilityInputTag, Info.AbilityType);
}

void USpellMenuWidgetController::EquipDragEnd()
{
	const FRPGGameplayTags GameplayTags = FRPGGameplayTags::Get();
	WaitForEquipSignature.Broadcast(GameplayTags.Abilities_None, GameplayTags.Abilities_Type_None);
}

然后我们在装配技能插槽里添加一个函数,用于设置当前插槽是否需要高亮,并判断输入标签如果一致,将无法高亮(没必要重复设置技能)
在这里插入图片描述
在高亮时,插槽显示一到光圈
在这里插入图片描述
这里我是编写了一个材质,可以根据运行时间调整亮度,类似于呼吸灯的效果
在这里插入图片描述
然后,我们在技能面板控制器里监听委托回调,调用设置高亮函数
在这里插入图片描述
设置高亮函数里,根据技能类型这里,根据匹配标签设置是否高亮,并将输入标签传入
在这里插入图片描述
然后将所有插槽调用自身的设置高亮
在这里插入图片描述

修改按钮

如果我们在一个用户控件里实现拖拽,并且,在里面添加了按钮,那么大概无法激活拖拽效果,因为鼠标事件将会被按钮阻挡,用户控件无法获取到对应的事件触发拖拽。

为了能够让拖拽事件顺利激活,这里我将按钮ui移出,使用一张图片替代
在这里插入图片描述
替换完成后,我们还是需要实现对应的按钮点击的效果,我们通过覆写鼠标相应的操作来模拟出鼠标点击按钮的效果。
在这里插入图片描述
在鼠标按下时,我们给定一个拖拽指针事件,当产生拖拽时,可以触发拖拽函数进行执行,然后我们添加了一个变量,用于定义鼠标被按下,并添加一个自定义事件,用来取消变量。
在这里插入图片描述
在自定义事件这里如果多次调用,在没到达延迟的时间时,将会重新延迟时间,在到达延迟时间后,将变量设置为false,在此时间后,抬起鼠标,将不会触发鼠标点击事件。
在这里插入图片描述
接下来就是处理鼠标悬停效果,我们可以通过鼠标进入和离开来判断鼠标是否悬停在UI上
在这里插入图片描述
后面设置就是指定一张图,然后在切换时,切换成对应的图片笔刷
在这里插入图片描述
接着就是在鼠标抬起事件里,我们其实就是复制了之前的鼠标点击事件,只是在前面添加了一个布尔判断,如果上面MouseDown变量被设置了false,就无法执行后面的点击事件
在这里插入图片描述
通过这样的一套操作,我们实现了模拟button的点击事件和鼠标悬停事件,如果还需要更细致的模拟,大家可以继续。

实现拖拽功能

接下来,到了重头戏了,就是拖拽功能,我们在技能按钮覆写发现拖动时,如果鼠标在按钮上按下,按照我们之前的配置,这个函数会被触发
在这里插入图片描述
在这个函数里,我们先判断是否是鼠标左键触发的拖拽
在这里插入图片描述
如果当前没有选中技能,我们需要激活当前技能的选中,(主要是为了让控制器保存我们拖拽的节点的技能标签,方便应用)

在这里插入图片描述
接着判断当前技能是否可以装配
在这里插入图片描述
调用我们之前编辑的让对应的可装配插槽高亮效果
在这里插入图片描述
我们还需要创建一个跟随拖拽的用户控件,这里,我对主动技能和被动技能做了区分,(因为它们的大小不一样),并设置显示的背景和图标
在这里插入图片描述
接下来,就是最重要的一步,通过内容创建拖拽操作,操作类我们可以进行自定义,这里直接使用的默认的,并将self作为自定义数据传输,并将创建的控件作为拖拽显示控件
在这里插入图片描述
接着,我覆写拖拽取消时,如果玩家放弃拖拽,我们需要将技能装配插槽恢复默认状态
在这里插入图片描述

在这里插入图片描述

实现拖拽事件的接收

接下来,我们需要在技能装配插槽里实现对拖拽事件的接收,对于拖拽事件的接收,有三个,发现拖拽进去,发现拖住啊离开,以及放置时
在这里插入图片描述
我们在拖动进入时,从数据中获取我们创建的对应数据
在这里插入图片描述
这里,我们对Payload转换为技能按钮,并判断当前是否能够高亮显示,判断条件就是输入标签不同,技能类型相同
在这里插入图片描述
然后就是对拖拽生成的UI上调用它的高亮函数
在这里插入图片描述
在这里插入图片描述
高亮的实现和技能装配插槽的高亮实现逻辑相同,额外增加一张图片,控制它的显示隐藏
在这里插入图片描述
如果拖拽离开此控件,我们将拖拽物体上的高亮效果取消
在这里插入图片描述
接着,我们再覆写放置时,就是玩家正确的放置了技能
在这里插入图片描述
我们在触发放置时,就和触发点击时一样,直接使用点击的事件即可
在这里插入图片描述
注意,将装配高亮效果取消掉,然后返回处理完成
在这里插入图片描述

接下来就是验证功能查缺补漏
在这里插入图片描述

处理委托的多次绑定

现在,我们关闭技能面板,然后再打开,会发现事件会被多次触发。
出现这个原因是,我们在创建控件时进行的委托绑定,但在关闭面板时,没有销毁。

解决这个问题,有两种方案,我先说第一种,就是我不会用的

我们可以在蓝图里,销毁控件是,调用取消绑定,可以指定函数取消指定回调事件,或者将所有委托全部取消掉,这种在蓝图实现起来有点乱。
在这里插入图片描述

接着就是介绍第二种方式,那就是实现一个函数,供蓝图调用,在控件销毁时,调用即可

我们在控制器基类里增加一个函数,用于清除委托绑定

	UFUNCTION(BlueprintCallable)
	virtual void ClearAllDelegate();  //清除全部委托绑定

并将在基类里绑定的委托清除掉

void URPGWidgetController::ClearAllDelegate()
{
	AbilityInfoDelegate.Clear();
}

在派生类里,我们首先覆写函数,

virtual void ClearAllDelegate() override;

然后在实现里,首先调用父类函数执行清除,接着实现在派生类里的委托变量的清除

void UAttributeMenuWidgetController::ClearAllDelegate()
{
	Super::ClearAllDelegate();

	AttributeInfoDelegate.Clear();
	AttributePointsChangedDelegate.Clear();
}

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

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

相关文章

鸿蒙内核源码分析(信号生产篇) | 注意结构体的名字和作用.

信号生产 关于信号篇&#xff0c;本只想写一篇&#xff0c;但发现把它想简单了&#xff0c;内容不多&#xff0c;难度极大.整理了好长时间&#xff0c;理解了为何<<深入理解linux内核>>要单独为它开一章&#xff0c;原因有二 信号相关的结构体多&#xff0c;而且…

RTC碰到LXTAL低频晶振停振怎么办?

GD32F303的RTC模块框图如下图所示&#xff0c;RTC时钟源可选择HXTAL/128、LXTAL或IRC40K&#xff0c;一般为了实现更精准的RTC时间&#xff0c;MCU系统均会外挂32.768KHz LXTAL低频晶振&#xff0c;但由于低频晶振负阻抗较大&#xff0c;不容易起振&#xff0c;若外部电路布线、…

vue3 antdv3 去掉Modal的阴影背景,将圆角边框改为直角的显示,看上去不要那么的立体的样式处理。

1、来个没有处理的效果图&#xff1a; 这个有立体的效果&#xff0c;有阴影的效果。 2、要处理一下样式&#xff0c;让这个阴影的效果去掉&#xff1a; 图片的效果不太明显&#xff0c;但是阴影效果确实没有了。 3、代码&#xff1a; /* 去掉遮罩层阴影 */.ant-modal-mask {…

Maven命令传pom或者jar异常

上传命令&#xff1a;mvn deploy:deploy-file -Durlhttp://****&#xff1a;****/repository/chntdrools7741-releases -DrepositoryId**** -DfileD:/tempRepo/org/kie/kie-api-parent/7.69.0.Final/kie-api-parent-7.69.0.Final.pom -DpomFileD:/tempRepo/org/kie/kie-api-par…

三级_网络技术_39_综合题(命令)

一、 如下图所示&#xff0c;某校园网用10Gbps 的POS技术与Internet相连&#xff0c;POS接网的幅格式早SDH。路由协议的选择方案是校园网内部采用OSPF协议&#xff0c;校园网与lntemnet的连接使用静态路由协议。校园网内的路由器R1设为DHCP服务器&#xff0c;可分配的IP地址是…

【22-54】创建者模式(详解五大模式)

目录 一.创建者模式介绍 二.单例设计模式 2.1 单例模式的结构 2.2 单例模式的实现 2.2.1.1 饿汉式-方式1&#xff08;静态变量方式&#xff09; 2.2.1.2 饿汉式-方式2&#xff08;静态代码块方式&#xff09; 2.2.2.1 懒汉式-方式1&#xff08;线程不安全&#xff09; 2…

用手机写一本电子书

第1步、进入Andi.cn网站 第2步、点击登录&#xff0c;注册用户 第3步、点击去创作&#xff0c;进入创作页面 第4步、点击右下角的小笔&#xff0c;写一篇文章 第5步、下翻&#xff0c;点击提交按钮 第6步、再写一篇文章 第7步、点击栏目设计 第8步、进入栏目设计&#xff0c;点…

excel卓越之道笔记

excel快捷键 1.Alt+=一键求和 2.Tab补全函数名称 3.CONCAT可以连选,CONCATENATE只能一个单元格一个单元格点选 4.excel365用不了phonetic函数,但是可以用concat代替 5.textjoin连接标识码,在Arcgis中筛选出所需要素,也是很好用的 6.法1:alt+; 定位可见单元格,复制后只…

Linux入门——01常用命令

0.命令行解释器shell 用户无法直接给操作系统指令&#xff0c;需要经过shell,才能让操作系统明白。如果用户对操作系统非法操作&#xff0c;会有shell保护。shell本身也是一个进程&#xff0c;当然&#xff0c;用户给shell的指令&#xff0c;shell会派生出子进程进行执行&#…

Unity Protobuf3.21.12 GC 问题(反序列化)

背景&#xff1a;Unity接入的是 Google Protobuf 3.21.12 版本&#xff0c;排查下来反序列化过程中的一些GC点&#xff0c;处理了几个严重的&#xff0c;网上也有一些分析&#xff0c;这里就不一一展开&#xff0c;默认读者已经略知一二了。 如果下面有任何问题请评论区留言提…

【Kubernetes中如何对etcd进行备份和还原】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

不同路径

不同路径 思路&#xff1a; 法一&#xff1a;动态规划 const int N 110; class Solution { int dp[N][N];//dp[i][j]&#xff1a;从起点走到 i j的路径个数。 public:int uniquePaths(int m, int n) {for(int i1;i<n;i){dp[1][i]1;} for(int i1;i<m;i) dp[i][1]1;f…

day36.动态规划+重载操作符

动态规划好难啊(ಥ﹏ಥ) 终于搞懂0-1背包问题的二维数组转一维数组优化的问题了。如图所示: 将二维数组转换成一位数组的核心就是&#xff0c;dp[i][j]选取时&#xff0c;他的值只与dp[i-1][j]&#xff0c;也就是上一行有关&#xff0c;所以可以引出使用一维数组代替二维数组…

python 使用宝塔面板在云服务器上搭建 flask

打开宝塔面板到【网站】&#xff0c;选择【python项目】&#xff0c;点【添加python项目】 填上相关信息&#xff1a; 注意&#xff1a;项目端口是你打算在外网用来访问flask的端口号 勾选【放行端口】&#xff0c;并提交 到阿里云里&#xff0c;选择安全组 手动添加放行端口…

datawind可视化查询-其他函数

飞书文档学习链接:https://www.volcengine.com/docs/4726/47275 1. 用户名函数 用户名函数并非 ClickHouse 官方函数,而是与项目用户信息相结合,用于返回当前使用用户的指定信息的函数。 USERNAME()可返回当前用户的用户名,如下所示。该函数也可与其他函数组合使用 2. J…

51 无显式主键时 mysql 增加的 DB_ROW_ID

前言 这里主要是 探讨, 在我们创建了一个 无主键的数据表, 然后 mysql 会为我们增加的这一个 DB_ROW_ID 的相关 新建一个无主键字段的数据表如下 CREATE TABLE implicit_id_table (username varchar(16) DEFAULT NULL,age int(11) DEFAULT NULL ) ENGINEInnoDB DEFAULT CH…

MySQL范围分区分区表

什么是范围分区分区表&#xff1f; 范围分区是一种根据某个列的范围值来分割表数据的分区方式。在范围分区中&#xff0c;每个分区都有自己的范围条件&#xff0c;当插入数据时&#xff0c;MySQL会根据指定的范围条件将数据分配到相应的分区中。这种分区方式可以使得表的数据按…

2024前端面试题-css篇

1.p和div区别 p自带有一定margin-top和margin-bottom属性值&#xff0c;而div两个属性值为0&#xff0c;也便是两个p之间有不一定间距&#xff0c;而div没有。 2.对css盒模型的理解 标准盒模型&#xff1a;content不包括padding、border、margin ie盒模型&#xff1a;conten…

关于我的生信笔记开通《知识星球》

关于知识星球 1. 为什么到现在才开通《知识星球》 从很早关注我的同学应该了解小杜的知识分享历程&#xff0c;小杜是从2021年11月底开始进入此“坑”&#xff0c;一直坚持到现在&#xff0c;马上3年了&#xff08;24年11月底到期&#xff09;。自己也从一个小青年&#xff0…

【图文并茂】ant design pro 如何统一封装好 ProFormSelect 的查询请求

你仔细看上面的图片吧 经常有这样的需求吧。 这些列表都是查询出来的。 后端 你的后端必须要有 api 。 const getUsers handleAsync(async (req: Request, res: Response) > {const { email, name, live, current 1, pageSize 10 } req.query;const query: any {};…