89. UE5 RPG 实现伤害 冷却 消耗技能描述
在上一篇文章里,我们能够通过富文本显示多种格式的文字,并显示技能描述。在这一篇文章里,我们继续优化技能描述,将技能说需要显示的内容显示出来。
实现火球术的基础描述
首先,我们现实现火球术的基础描述,它属于投掷物类型的技能,触发技能会发射多个投掷物。我们实现原理就是覆写积累的获取技能描述的函数,来实现定义火球术的描述。
public:virtual FString GetDescription(int32 Level) override; //获取投射技能描述virtual FString GetNextLevelDescription(int32 Level) override; //获取投射技能下一等级描述
然后实现,如果需要换行,我们在字符串里是通过\n
来实现切换一行
FString UProjectileSpell::GetDescription(int32 Level)
{const int32 ScaledDamage = DamageTypes[FRPGGameplayTags::Get().Damage_Fire].GetValueAtLevel(Level); //根据等级获取技能伤害if(Level == 1){return FString::Printf(TEXT("<Title>火球术</>\n<Small>等级:1</>\n\n<Default>发射 1 颗火球,在发生撞击时产生爆炸,并造成</> <Damage>%i</> <Default>点火焰伤害,并有一定几率燃烧。</>"), ScaledDamage);}return FString::Printf(TEXT("<Title>火球术</>\n<Small>等级:%i</>\n\n<Default>发射 %i 颗火球,在发生撞击时产生爆炸,并造成</> <Damage>%i</> <Default>点火焰伤害,并有一定几率燃烧。</>"), Level, FMath::Min(Level, NumProjectiles), ScaledDamage);
}FString UProjectileSpell::GetNextLevelDescription(int32 Level)
{const int32 ScaledDamage = DamageTypes[FRPGGameplayTags::Get().Damage_Fire].GetValueAtLevel(Level + 1); //根据等级获取技能伤害return FString::Printf(TEXT("<Title>下一等级</>\n<Small>等级:%i</>\n\n<Default>发射 %i 颗火球,在发生撞击时产生爆炸,并造成</> <Damage>%i</> <Default>点火焰伤害,并有一定几率燃烧。</>"), Level, FMath::Min(Level, NumProjectiles), ScaledDamage);
}
接着运行查看效果
创建火球术类
为了能够保证火球术文本不影响其它投掷物技能,我们要基于投掷物技能类创建一个它的子类,这样,我们修改火球术的技能描述,只会应用给火球术。
接着,我们将火球术的GA的父类修改为我们新创建的子类
获取冷却和技能消耗
为了能够在技能描述里显示技能冷却时间和技能的消耗,我们需要是现对应的函数获取
我们在技能基类里增加两个函数,用于获取冷却和消耗,它们是保护性的,只有它或者派生类才可以调用
protected:float GetManaCost(float InLevel = 1.f) const; //获取技能蓝量消耗float GetCooldown(float InLevel = 1.f) const; //获取技能冷却时间
GAS框架给我们封装了获取对应的GE的函数,我们可以直接通过函数获取,并且从修改项种获取对应的修改属性进行判断,并获取对应的等级的结果。
float URPGGameplayAbility::GetManaCost(const float InLevel) const
{float ManaCost = 0.f;//获取到冷却GEif(const UGameplayEffect* CostEffect = GetCostGameplayEffect()){//遍历GE修改的内容for(FGameplayModifierInfo Mod : CostEffect->Modifiers){//判断修改的属性是否为角色蓝量属性if(Mod.Attribute == URPGAttributeSet::GetManaAttribute()){//通过修饰符获取到使用的FScalableFloat并计算传入等级的蓝量消耗,FScalableFloat是受保护性的属性,无法直接获取,只能通过函数Mod.ModifierMagnitude.GetStaticMagnitudeIfPossible(InLevel, ManaCost);break; //获取到了就结束遍历}}}return ManaCost;
}float URPGGameplayAbility::GetCooldown(const float InLevel) const
{float Cooldown = 0.f;//获取到技能冷却GEif(const UGameplayEffect* CooldownEffect = GetCooldownGameplayEffect()){//获取到当前冷却时间CooldownEffect->DurationMagnitude.GetStaticMagnitudeIfPossible(InLevel, Cooldown);}return Cooldown;
}
然后我们在伤害技能类里(所有具有伤害的技能类都继承至它)添加一个根据伤害类型获取伤害数值的函数,伤害类型是我们通过标签添加注册
float GetDamageByDamageType(float InLevel, const FGameplayTag& DamageType); //根据伤害类型获取伤害
然后我们根据配置的配置里,获取对应的标签的曲线图表,来获取对应等级的伤害
float URPGDamageGameplayAbility::GetDamageByDamageType(const float InLevel, const FGameplayTag& DamageType)
{checkf(DamageTypes.Contains(DamageType), TEXT("技能 [%s] 没有包含 [%s] 类型的伤害"), *GetNameSafe(this), *DamageType.ToString());return DamageTypes[DamageType].GetValueAtLevel(InLevel); //根据等级获取技能伤害
}
需要的数值都能够获取到,接着,我们在火球技能里覆写获取描述的函数
UCLASS()
class RPG_API URPGFireBolt : public UProjectileSpell
{GENERATED_BODY()public:// FString GetDescriptionAtLevel(int32 INT32, const char* Str);virtual FString GetDescription(int32 Level) override; //获取投射技能描述virtual FString GetNextLevelDescription(int32 Level) override; //获取投射技能下一等级描述FString GetDescriptionAtLevel(int32 Level, const FString& Title); //获取对应等级的技能描述
};
由于函数的重复代码太过,我就增加了一个通过等级获取技能描述的函数,并且可以自定义标题,当前等级和下一等级的技能描述的标题不同。
这里需要注意的点是,字符串也可以多个拼接,并且你如果输入的是浮点数,可以通过设置%.1f这样的写法来设置它的分段,防止有太小的数值出现。
FString URPGFireBolt::GetDescription(const int32 Level)
{return GetDescriptionAtLevel(Level, L"火球术");
}FString URPGFireBolt::GetNextLevelDescription(const int32 Level)
{return GetDescriptionAtLevel(Level, L"下一等级");
}FString URPGFireBolt::GetDescriptionAtLevel(const int32 Level, const FString& Title)
{const int32 Damage = GetDamageByDamageType(Level, FRPGGameplayTags::Get().Damage_Fire);const float ManaCost = GetManaCost(Level);const float Cooldown = GetCooldown(Level);return FString::Printf(TEXT(// 标题"<Title>%s</>\n"// 细节"<Small>等级:</> <Level>%i</>\n""<Small>技能冷却:</> <Cooldown>%.1f</>\n""<Small>蓝量消耗:</> <ManaCost>%.1f</>\n\n"//%.1f会四舍五入到小数点后一位// 技能描述"<Default>发射 %i 颗火球,在发生撞击时产生爆炸,并造成</> <Damage>%i</> <Default>点火焰伤害,并有一定几率燃烧。</>"),// 动态修改值*Title,Level,Cooldown,ManaCost,FMath::Min(Level, NumProjectiles),Damage);
}
接着,编译打开项目测试效果。
实现技能取消选中功能
接下来,我们再实现一个小功能,就是在第二次点击技能的时候,取消技能选中状态。
这个功能的实现,需要我们取消选中的时候,要取消掉技能显示的升降级按钮和等级显示。并且要将技能描述里的内容清空。
我们在技能面板控制器增加一个新的蓝图调用函数,用于技能按钮取消选中时调用
UFUNCTION(BlueprintCallable)void GlobeDeselect(); //取消按钮选中处理
在函数实现这里,重置缓存的内容,并广播清空技能描述的内容。
void USpellMenuWidgetController::GlobeDeselect()
{const FRPGGameplayTags GameplayTags = FRPGGameplayTags::Get();SelectedAbility.Ability = GameplayTags.Abilities_None;SelectedAbility.Status = GameplayTags.Abilities_Status_Locked;SelectedAbility.Level = 0;SpellDescriptionSignature.Broadcast(FString(), FString());
}
有了此函数,打开技能按钮的蓝图在触发取消选中时,调用自身取消状态,并调用刚添加的函数清空技能描述,播放一个取消选中音效。
防止未添加标签显示技能描述内容
我发现在选中锁定按钮,并锁定按钮没有设置对应的数据时,还会显示技能在多少等级后解锁,为了解决这个问题,我们在ASC函数获取技能描述时,添加判断,如果技能标签未设置,或设置为空,则返回空内容
bool URPGAbilitySystemComponent::GetDescriptionByAbilityTag(const FGameplayTag& AbilityTag, FString& OutDescription, FString& OutNextLevelDescription)
{//如果当前技能处于锁定状态,将无法获取到对应的技能描述if(FGameplayAbilitySpec* AbilitySpec = GetSpecFromAbilityTag(AbilityTag)){if(URPGGameplayAbility* RPGAbility = Cast<URPGGameplayAbility>(AbilitySpec->Ability)){OutDescription = RPGAbility->GetDescription(AbilitySpec->Level);OutNextLevelDescription = RPGAbility->GetNextLevelDescription(AbilitySpec->Level + 1);return true;}}//如果技能是锁定状态,将显示锁定技能描述const UAbilityInfo* AbilityInfo = URPGAbilitySystemBlueprintLibrary::GetAbilityInfo(GetAvatarActor());if(!AbilityTag.IsValid() || AbilityTag.MatchesTagExact(FRPGGameplayTags::Get().Abilities_None)){OutDescription = FString();}else{OutDescription = URPGGameplayAbility::GetLockedDescription(AbilityInfo->FindAbilityInfoForTag(AbilityTag).LevelRequirement);}OutNextLevelDescription = FString();return false;}
相关文章:
89. UE5 RPG 实现伤害 冷却 消耗技能描述
在上一篇文章里,我们能够通过富文本显示多种格式的文字,并显示技能描述。在这一篇文章里,我们继续优化技能描述,将技能说需要显示的内容显示出来。 实现火球术的基础描述 首先,我们现实现火球术的基础描述࿰…...
el-tree树状控件,定位到选中的节点的位置
效果图 在el-tree 控件加 :render-content"renderContent" 在掉接口的方法中 实际有用的是setTimeout 方法和this.$refs.xxxxxx.setCheckedKeys([industrycodeList]) if(res.data.swindustrylist.length>0){res.data.swindustrylist.forEach(item > {industry…...
YOLO目标检测的单目(多目标测距),使用相机光学模型,支持目标检测模型训练,可输出目标位置和距离信息并可视化
本项目旨在开发一个基于YOLO的目标检测系统,该系统不仅能检测图像中的多个目标,还能利用单目摄像头的图像估计每个目标与摄像头之间的相对距离。系统的核心组成部分包括目标检测、距离估计、模型训练以及结果可视化。 主要功能 目标检测:使用…...
unity简易lua文件迁移工具
一. 了解商业游戏的Lua热更新开发方式 市面上的3种结合Lua热更新的开发方式 1.纯Lua开发(所有的游戏主要逻辑都用Lua实现) 好处:机动性强;坏处:代码效率略差 2.半C#,半Lua开发(核心逻辑C#开发…...
Elasticsearch中的自动补全功能详解与实践
简介 自动补全是现代搜索引擎中的一项重要功能,它能够根据用户的输入提供实时的建议,提高用户体验。Elasticsearch提供了Completion Suggester查询来实现这一功能。本文将详细介绍Elasticsearch中的自动补全功能,并提供详细的配置和查询示例…...
前端如何使用Nginx代理dist网页,代理websocket,代理后端
本文将指导您如何配置Nginx以代理前后端分离的项目,并特别说明了对WebSocket的代理设置。通过本教程,您将能够实现一次性配置,进而使项目能够在任意局域网服务器上部署,并可通过IP地址或域名访问服务。 笔者建议 先速览本文了解大…...
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. 问题解决
问题描述 原来我的服务器docker服务运行正常,但在某次尝试用时, 根据系统的错误提示执行了snap install docker指令之后, 再执行docker ps命令则提示Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running…...
零基础学习Redis(2) -- Redis安装与配置
Redis官方是并不支持Windows系统的,并且现在绝大部分公司都是使用的Linux,所以我们在Linux上进行安装,这里我使用的是Ubuntu 1. 安装步骤 1. 首先使用工具连接到我们的云服务器,然后输入apt指令搜索redis相关的软件包࿱…...
UniApp第一天
一、官网介绍 1.1、 SDK SDK是"Software Development Kit"的缩写,中文意思是“软件开发工具包”。SDK通常是由软件开发者为其他开发者提供的一个软件工具集合,用于帮助开发者快速开发、测试和部署软件应用。SDK通常包含了一系列的开发工具、库…...
TLE4966-3G带方向检测功能的高灵敏度汽车霍尔开关
TLE4966-3G是一款集成电路双霍尔效应传感器,专为使用旋转极轮的高精度应用而设计。通过片上有源补偿电路和斩波器技术实现精确的磁切换点和高温稳定性。 该传感器在Q2提供速度输出,其状态(高或低)与磁场值相对应。对于超过阈值BO…...
Github 2024-08-14 C开源项目日报Top10
根据Github Trendings的统计,今日(2024-08-14统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10Objective-C项目1PHP项目1Python项目1PHP:流行的Web开发脚本语言 创建周期:4710 天开发语言:C, PHP协议类型:OtherStar数量:37340 …...
飞桨Paddle API index_add 详解
index_add paddle.index_add(x, index, axis, value, nameNone)[源代码] 沿着指定轴 axis 将 index 中指定位置的 x 与 value 相加,并写入到结果 Tensor 中的对应位置。这里 index 是一个 1-D Tensor。除 axis 轴外,返回的 Tensor 其余维度大小和输入 …...
后端代码练习1——加法计算器
1. 需求 输入两个整数,点击 “点击相加” 按钮,显示计算结果。 2.准备工作 创建Spring Boot项目,引入Spring Web依赖,把前端代码放入static目录下。 2.1 前端代码 <!DOCTYPE html> <html lang"en"> <h…...
观察者模式和MQ是什么关系
观察者模式(Observer Pattern)和MQ(Message Queue,消息队列)之间的关系主要体现在它们所实现的功能和机制上的相似性,尽管它们在技术实现和应用场景上有所不同。 观察者模式 观察者模式是一种行为型设计模…...
JDK动态代理和CGLIB动态代理案例分析
JDK动态代理和CGLIB动态代理案例分析 JDK动态代理和CGLIB动态代理的实现原理如下: JDK动态代理的实现原理: JDK动态代理是基于Java的反射机制实现的实现一个继承InvocationHandler接口的对象,重写invoke方法,invoke方法中可以在目…...
【数据结构-前缀哈希】力扣1124. 表现良好的最长时间段
给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格 大…...
电商平台产品ID|CDN与预渲染|前端边缘计算
技术实现 都是通过ID拿到属性,进行预渲染html,通过 oss 分发出去 详情页这种基本都是通过 ssr 渲染出来,然后上缓存 CDN 分发到边缘节点来处理,具体逻辑可以参考 淘宝——EdgeRoutine边缘计算(CDNServerless 边缘计算…...
LATTICE进阶篇DDR2--(4)DDR2 IP核总结
一、IP核的时钟框架 1片DDR2的接口是16位,且DDR2是双边沿读取的, 故当DDR2芯片的时钟为200M时,右侧DDR2芯片上的数据吞吐率为200M*2*16b,左侧数据吞吐率为200M*32b,左右两侧数据吞吐量相等。 根据上规律可知…...
windows下php安装kafka
下载zookeeper Kafka 依赖 Zookeeper 进行分布式协调,所以需要下载Zookeeper ,当然你也可以使用kafka包里自带的一个默认配置的 Zookeeper。这里我们单独下载一个 访问Zookeeper官方下载页面在页面中找到最新的稳定版本,点击相应的下载链接…...
【wiki知识库】09.欢迎页面展示(浏览量统计)SpringBoot部分
🍊 编程有易不绕弯,成长之路不孤单! 大家好,我是熊哈哈,这个项目从我接手到现在有了两个多月的时间了吧,其实本来我在七月初就做完的吧,但是六月份的时候生病了,在家里休息了一个月的…...
数据分析与应用:微信-情人节红包流向探索分析
目录 0 需求描述 1 红包发送方用户的基本信息缺失率有多高?(即有多少红包发送方用户无法在用户基本信息表中匹配? 2 哪一组红包金额的拒收率最高? 3、最受二线城市欢迎的红包金额为?(即发出次数最多) 4 北上广深 4 大城市中,哪座城市的男性用户发出的 520 红包比例…...
SQL,获取 ID 的历史状态
sas系统的表tb存储病人的医疗历史记录,当Visit_codeSurgery时表示手术,Visit_codeOffice表示咨询,每个病人有多条Visit_code,有时只有Surgery或只有Office:IdVisit_DateVisit_codeA305/15/2004SurgeryA302/5/2005Offic…...
阅文集团:摇不动的IP摇钱树
把IP当成摇钱树,要做“东方迪士尼” 今天我们聊——阅文集团 《热辣滚烫》《庆余年2》《与凤行》和《玫瑰的故事》很熟悉吧?影视“四连爆”, 阅文集团交出一份亮眼半年报,时隔两年,重启增长。 跟IP相关业务对收入贡献…...
ETL数据集成丨将SQL Server数据同步至Oracle的具体实现
一、背景 在构建企业级数据架构时,将SQL Server数据库的数据同步至数仓数据库(如Oracle)是一项至关重要的任务。这一过程不仅促进了跨系统数据的一致性与可用性,还为数据分析、商业智能以及决策支持系统提供了坚实的数据基础。 …...
20240814软考架构-------软考51-55答案解析
每日打卡题51-55答案 51、【2017年真题】 难度:一般 系统移植也是系统构建的一种实现方法,在移植工作中, 需要最终确定移植方法。 A.计划阶段 B.准备阶段 C.转换阶段 D.验证阶段 答案:A 解析: 移植工作大体上分为计划…...
JavaEE 的入门
1. 学习JavaEE Java EE(Java Platform Enterprise Edition), Java 平台企业版. 是JavaSE的扩展, ⽤于解决企业级的开 发需求, 所以也可以称之为是⼀组⽤于企业开发的Java技术标准. 所以, 学习JavaEE主要是学习Java在 企业中如何应⽤. 前⾯学习的是Java基础, JavaEE 主要学习Jav…...
vue3+ts 前端word文档下载文件时不预览直接下载方法(支持 doc / excel / ppt / pdf 等)
前端word文档下载文件时不预览直接下载方法支持 doc / excel / ppt / pdf 等 根据需要,要实现一个下载文档的需要 最简单的方法就是使用a标签 如果是相同域可以直接下载,但如果是不同域的,就会先打开一个预览页,在预览页再点下载…...
Java 空值与null 形参与实参学习
Java系列文章目录 文章目录 Java系列文章目录一、前言二、学习内容:三、问题描述四、解决方案:4.1 空值与null的区别4.1.1 空值(Empty Value)4.1.2 Null 4.2 形参与实参区别 五、总结:5.1 学习总结: 一、前…...
【QT常用技术讲解】QTableView添加QCheckBox、QPushButton
前言 QT展示列表信息的时候通常用到列表(比如用户信息、机构信息、设备信息等菜单),当需要对某列进行修改、删除操作时,就需要加入按钮(QPushButton),当需要对多列进行右键菜单操作时࿰…...
linux监控命令
在 Linux 中,有许多命令可以用于监控系统的性能和状态。以下是一些常用的监控命令及其用途: 1. top 和 htop top top 命令显示当前系统中运行的进程列表及其资源使用情况。 top htop htop 是 top 命令的增强版,提…...
成都建站seo/建一个外贸独立站大约多少钱
1 构造函数 1.1 对象的初始化 在定义一个对象的时候,常常需要作某些初始化的工作,例如,对成员变量赋值。如果一个成员变量未赋值,那么,它的值是不可预知的(是系统随机分配的一个垃圾值)。因为系…...
七合一小程序saas平台/培训seo
由于低版本浏览器不支持css3 animation,因此我们需要根据浏览器来选择不同的动画引擎。如果浏览器支持css3 animation,那么就使用此动画引擎,如果不支持,就使用javascript的动画引擎。 首先,我们看一下判定条件&#x…...
我想克隆个网站 怎么做/女生学网络营销这个专业好吗
安装MySQLdb pip install MySQLdb安装不成功请使用离线安装方式,pypi:https://pypi.org/project/mysqlclient/#files 选择对应的Python版本,下载.whl文件,并离线安装 pip install mysqlclient-2.0.3-cp37-cp37m-win_amd64.whl操…...
wordpress入门教程(视频)/百度推广外推联系方式
AVR c语言优秀编程风格作为一个初学者如何具有良好的程序设计风格呢?我想引用一个关于初学者请教编程大师的故事让读者自己去领悟。有一位编程大师,他写非结构化的程序,一位初学者刻意模仿他,也写非结构化的程序。当他让大师看他的…...
响应式网站开发的理解/培训课程网站
r 输出自动生成文件我被要求为我当地大学的下一学期设计新课程。 从历史上看,我使用Power Point创建课程幻灯片,并使用Word创建实验说明。 对于幻灯片和文档,还有其他可能的替代方法: Google幻灯片 一堆JavaScript框架࿰…...
怎么制作网站栏目页主页/seo可以从哪些方面优化
在上一篇文章《欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行》中我们对STM32启动前的汇编部分的代码进行了分析。今天来一篇硬件设计方面的文章,教大家如何安装Altium Designer18。目前最新的Altium Designer最新版已经到了Altium Designer20&…...