当前位置: 首页 > news >正文

93. UE5 GAS RPG 应用负面效果表现

在上一篇文章里,我们实现了添加负面效果GE,并且在添加GE时,也会给角色应用一个负面效果标签作为标识。在这一篇里,我们将通过负面效果标签标识,应用角色身上展现对应的负面效果的表现。
我们将在这篇文章里添加一个自定义的Niagara组件,来实现对应的负面效果表现,并通过观察角色身上是否应用的对应的标签,来激活和取消激活组件。

解决应用标签的bug

首先我们解决之前编写的通过代码设置GE标签的方法。
和之前的相比,有两处问题,第一处就是不应该直接获取,而是直接创建一个新的FInheritedTagContainer。
第二处是在添加的地方需要设置到Added对象上,对应UE里设置GE。

UTargetTagsGameplayEffectComponent& TargetTagsGameplayEffectComponent = Effect->AddComponent<UTargetTagsGameplayEffectComponent>();
FInheritedTagContainer InheritableOwnedTagsContainer; //创建组件所需的标签容器
InheritableOwnedTagsContainer.Added.AddTag(DeBuffType); //添加标签
TargetTagsGameplayEffectComponent.SetAndApplyTargetTagChanges(InheritableOwnedTagsContainer); //应用并更新

创建自定义的Niagara组件类

为了能够自定义负面效果表现的自动开关功能,我们需要自己扩展Niagara类,在里面增加内容。
我们基于NiagaraComponent创建一个派生类
在这里插入图片描述
设定好相关名称和目录
在这里插入图片描述
在派生类里,我们添加构造函数,设置标识当前对应的负面效果的标签,以及对应标签变动回调以及角色死亡回调。

UCLASS()
class RPG_API UDeBuffNiagaraComponent : public UNiagaraComponent
{GENERATED_BODY()public:UDeBuffNiagaraComponent();UPROPERTY(EditDefaultsOnly)FGameplayTag DeBuffTag; //用来标识粒子系统的标签protected:virtual void BeginPlay() override; //覆写开始运行void DeBuffTagChanged(const FGameplayTag CallbackTag, int32 NewCount); //当前的负面标签变动回调UFUNCTION()void OnOwnerDeath(AActor* DeadActor); //在角色死亡时的回调
};

在构造函数中,我们将自动激活关闭

UDeBuffNiagaraComponent::UDeBuffNiagaraComponent()
{bAutoActivate = false; //关闭自动激活
}

在事件开始执行时,我们绑定对应的回调,用来检测角色的变动,并在变动时触发回调

void UDeBuffNiagaraComponent::BeginPlay()
{Super::BeginPlay();ICombatInterface* CombatInterface = Cast<ICombatInterface>(GetOwner()); //获取到战斗接口//通过函数库获取角色身上的ASCif(UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(GetOwner())){//监听负面标签变动回调ASC->RegisterGameplayTagEvent(DeBuffTag, EGameplayTagEventType::NewOrRemoved).AddUObject(this, &UDeBuffNiagaraComponent::DeBuffTagChanged);}else if(CombatInterface) //如果绑定时,ASC未初始化成功,则监听ASC创建完成委托,完成对负面标签的监听{//AddWeakLambda 这种绑定方式的主要好处是,当绑定的对象被销毁时,委托不会保持对象的引用,从而避免悬空指针问题和内存泄漏。CombatInterface->GetOnASCRegisteredDelegate().AddWeakLambda(this,[this](UAbilitySystemComponent* InASC){//监听负面标签变动回调InASC->RegisterGameplayTagEvent(DeBuffTag, EGameplayTagEventType::NewOrRemoved).AddUObject(this, &UDeBuffNiagaraComponent::DeBuffTagChanged);});}//绑定死亡后销毁if(CombatInterface){CombatInterface->GetOnDeathDelegate().AddDynamic(this, &UDeBuffNiagaraComponent::OnOwnerDeath);}
}

监听负面效果标签的回调里,我们可以获取角色身上对应标签的个数,如果不为0,则激活粒子

void UDeBuffNiagaraComponent::DeBuffTagChanged(const FGameplayTag CallbackTag, int32 NewCount)
{if(NewCount > 0){Activate(); //绑定的负面标签大于0,激活特效}else{Deactivate(); //没有对应标签,关闭激活}
}

在触发死亡回调时,关闭激活

void UDeBuffNiagaraComponent::OnOwnerDeath(AActor* DeadActor)
{Deactivate();
}

添加对应委托

在自定义Niagara组件里,我们需要两个委托来监听角色身上的负面标签变动以及角色是否死亡
在战斗接口类里,我们增加两个委托,可以通过其进行绑定
Dynamic的区别在于能不能绑定蓝图,非Dynamic的无法绑定,Dynamic的需要通过UE反射绑定,也可以直接蓝图获取绑定。

DECLARE_MULTICAST_DELEGATE_OneParam(FOnASCRegistered, UAbilitySystemComponent*); //Actor初始化ASC完成后委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnDeath, AActor*, DeadActor); //Actor死亡后的委托

然后我们在类里增加两个获取函数,可以获取对应的委托,这里我们需要返回引用

	virtual FOnASCRegistered& GetOnASCRegisteredDelegate() = 0; //获取ASC注册成功后的委托virtual FOnDeath& GetOnDeathDelegate() = 0; //获取死亡委托

接着,我们在角色基类里增加两个对应的委托

	FOnASCRegistered OnASCRegistered; //ASC注册成功委托FOnDeath OnDeath; //角色死亡后触发的死亡委托

覆写两个函数

	virtual FOnASCRegistered& GetOnASCRegisteredDelegate() override; //获取ASC注册成功委托virtual FOnDeath& GetOnDeathDelegate() override; //角色死亡委托

对其实现一下,返回对应的委托

FOnASCRegistered& ARPGCharacter::GetOnASCRegisteredDelegate()
{return OnASCRegistered;
}FOnDeath& ARPGCharacter::GetOnDeathDelegate()
{return OnDeath;
}

触发委托

现在我们创建完成了对应的委托,还需要在合适的位置对其进行广播
首先是ASC创建完成后的广播,我选择在InitAbilityActorInfo函数里,创建完成ASC后广播

void ARPGEnemy::InitAbilityActorInfo()
{AbilitySystemComponent->InitAbilityActorInfo(this, this);Cast<URPGAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet();//通过GE初始角色的属性if(HasAuthority()){InitializeDefaultAttributes();}//调用ASC广播OnASCRegistered.Broadcast(AbilitySystemComponent);
}

角色的函数内容不同,在函数执行完时,也完成了广播

void ARPGHero::InitAbilityActorInfo()
{ARPGPlayerState* PlayerStateBase = GetPlayerState<ARPGPlayerState>();check(PlayerStateBase); //检测是否有效,无限会暂停游戏//从playerState获取ASC和ASAbilitySystemComponent = PlayerStateBase->GetAbilitySystemComponent();AttributeSet = PlayerStateBase->GetAttributeSet();//初始化ASCAbilitySystemComponent->InitAbilityActorInfo(PlayerStateBase, this);//触发Actor的技能信息设置回调Cast<URPGAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet(); //获取PCif(ARPGPlayerController* PlayerControllerBase = Cast<ARPGPlayerController>(GetController())){if(ARPGHUD* HUD = Cast<ARPGHUD>(PlayerControllerBase->GetHUD())){HUD->InitOverlay(PlayerControllerBase, PlayerStateBase, AbilitySystemComponent, AttributeSet);}}//通过GE初始角色的属性InitializeDefaultAttributes();//调用ASC广播OnASCRegistered.Broadcast(AbilitySystemComponent);
}

然后就是角色的死亡委托广播,我们之前创建了一个多播函数,在角色死亡后,每个游戏端都会触发此函数

void ARPGCharacter::MulticastHandleDeath_Implementation()
{//播放死亡音效UGameplayStatics::PlaySoundAtLocation(this, DeathSound, GetActorLocation());//开启武器物理效果Weapon->SetSimulatePhysics(true); //开启模拟物理效果Weapon->SetEnableGravity(true); //开启重力效果Weapon->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道//开启角色物理效果GetMesh()->SetSimulatePhysics(true); //开启模拟物理效果GetMesh()->SetEnableGravity(true); //开启重力效果GetMesh()->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道GetMesh()->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block); //开启角色与静态物体产生碰撞//关闭角色碰撞体碰撞通道,避免其对武器和角色模拟物理效果产生影响GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);//设置角色溶解Dissolve();//设置死亡状态bDead = true;//触发死亡委托OnDeath.Broadcast(this);
}

在蓝图编辑

接着,我们在角色积累增加一个Niagara组件,设置火的负面效果

	UPROPERTY(VisibleAnywhere) //火焰负面效果表现组件TObjectPtr<UDeBuffNiagaraComponent> BurnDeBuffComponent;

在构造函数里初始化,并设置好对应的负面标签

	//初始化火焰负面效果组件BurnDeBuffComponent = CreateDefaultSubobject<UDeBuffNiagaraComponent>("BurnDeBuffComponent");BurnDeBuffComponent->SetupAttachment(GetRootComponent());BurnDeBuffComponent->DeBuffTag = FRPGGameplayTags::Get().DeBuff_Burn; //设置匹配的负面标签

编译打开UE,可以看到,里面增加了对应的组件
在这里插入图片描述
我们可以在组件上设置使用的Niagara资产
在这里插入图片描述
还可以修改对应的DeBuff标签
在这里插入图片描述
实现完成后,我们需要进行测试,测试的主要内容是

  1. 在激活负面效果时,是否能够正确激活Niagara
  2. 在负面效果结束时,标签是否能够在角色身上正确清除,Niagara是否能够自动结束
  3. 在激活负面效果时,角色死亡是否能够自动停止激活等待销毁。
    如果都没有问题,基本上效果实现完毕。

相关文章:

93. UE5 GAS RPG 应用负面效果表现

在上一篇文章里&#xff0c;我们实现了添加负面效果GE&#xff0c;并且在添加GE时&#xff0c;也会给角色应用一个负面效果标签作为标识。在这一篇里&#xff0c;我们将通过负面效果标签标识&#xff0c;应用角色身上展现对应的负面效果的表现。 我们将在这篇文章里添加一个自定…...

TCP 和 UDP 区别

UDP UDP&#xff08;用户数据报协议&#xff0c;User Datagram Protocol&#xff09;是一种无连接的网络传输协议&#xff0c;提供了简单的消息传送服务。UDP位于传输层&#xff0c;允许应用程序向其他主机发送封装在IP数据报中的消息&#xff0c;而无需先建立连接。由于UDP不…...

免费2024柜台租赁经营合同范本模板下载分享

今天看到这个合同范本都拿来卖钱,我直接分享出来2024年最新的范本模板随便下,免费的 柜台租赁经营合同GF—2013—0603.docx: https://url51.ctfile.com/f/20096151-1353625109-4285d2?p1605 (访问密码: 1605) 柜台租赁经营合同GF—2013—0603.pdf: https://url51.ctfile.com/…...

模型和算力看板:Compute DashBoard

AGI 之路 AGI&#xff08;通用人工智能&#xff09;是整个计算机科学的圣杯&#xff0c;算力的增长和模型能力的提升&#xff08;算法和数据&#xff09;缺一不可。作为一个新质生产力&#xff0c;构建一个合理的评价体系是常用的方法论。针对模型和算力的评价&#xff0c;有类…...

Python加载 TorchScript 格式的 ResNet18 模型分类该模型进行预测并输出预测的类别和置信度

首先加载预训练的 ResNet18 模型。将模型设置为评估模式&#xff0c;以确保特定层&#xff08;如 Dropout 和 BatchNorm&#xff09;在评估时具有确定性的行为。创建一个形状为 (1, 3, 224, 224) 的随机张量作为示例输入。使用 torch.jit.trace 函数追踪模型在给定示例输入上的…...

学习笔记--MybatisPlus

官网&#xff1a;MyBatis-Plus &#x1f680; 为简化开发而生 快速入门 入门案例 引入MybatisPlus的起步依赖 定义Mapper 问题&#xff1a; MybatisPlus中Invalid bound statement (not found): com.itheima.mp.mapper.UserMapper.insert 一定要指定实体类&#xff01;&am…...

【机器学习】XGBoost的用法和参数解释

一、XGBoost的用法 流程&#xff1a; 代码案例&#xff1a; 二、XGBoost的几大参数 1、一般参数&#xff0c;用于集成算法本身 ①n_estimators 集成算法通过在数据上构建多个弱 评估器&#xff0c;汇总所有弱评估器的建模结果&#xff0c;以获取比单个模型更好的回归或分类…...

Vivado 约束

步骤5&#xff1a;保存约束 约束管理是设计流程的重要一步&#xff0c;Vivado设计套件 为您提供了在现有约束文件中添加新约束、覆盖的灵活性 现有约束&#xff0c;或创建新的约束文件以跟踪设计更改或完成 缺少约束。 您为设计创建了一些定时异常&#xff0c;但这些异常仅存在…...

如何在Excel中创建一个VBA宏,并设置一个按钮来执行这个宏

下面是一个详细的步骤指南 步骤1&#xff1a;创建VBA宏 1. 打开Excel并按 Alt F11 打开VBA编辑器。 2. 在VBA编辑器中&#xff0c;选择 Insert > Module 来插入一个新的模块。 3. 将以下代码粘贴到模块中&#xff1a; vba Sub CreateNewSheet() 声明一个工作表对象Dim …...

H3C SR-MPLS通过OSPF通告SID配置

首先在配置前理解几个基本概念 Prefix SID配置 统一分配和配置&#xff08;全局规划&#xff09;loopback和prefix sidPrefix SIDSRGB Base&#xff08;16000&#xff09;index Adj SID自动生成 对应SR节点间的互联链路SR节点本地标识&#xff0c;从设备本地Segment池中动态…...

JS面试真题 part2

JS面试真题 part2 6、typeof 与 instanceof 区别7、JavaScript原型&#xff0c;原型链&#xff1f;有什么特点8、说说你对作用域链的理解9、谈谈this对象的理解10、说说new操作符具体干了什么 6、typeof 与 instanceof 区别 自己回答&#xff1a; typeof&#xff1a;用来判断数…...

python 下载excel 添加水印

Python 在 Excel 中添加水印 https://zhuanlan.zhihu.com/p/499239298 生成图片 from PIL import Image, ImageDraw, ImageFont import numpy as np import matplotlib.pyplot as plt# 创建一个新的白色图片 img Image.new(RGB, (200, 100), color(255, 255, 255))# 指定中…...

CosyVoice:开源强大的 AI 语音合成工具

在当今科技飞速发展的时代&#xff0c;AI 语音合成技术正逐渐改变着我们的生活。今天&#xff0c;就为大家介绍一款卓越的语音合成工具——CosyVoice。 一、安装步骤 克隆和安装&#xff1a; 克隆仓库&#xff1a;git clone --recursive https://github.com/FunAudioLLM/Cos…...

【靶场】Pikachu—XSS Cross-Site Scripting(前五关)

&#x1f3d8;️个人主页&#xff1a; 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞&#x1f44d;收藏&#x1f497;支持一下哦 【靶场】Pikachu—XSS Cross-Site Scripting&#xff08;前五关&#xff09; 第一关 反射型xss(get)第二关 反射型xss(post)第三关…...

Dance with Compiler - EP2

今天来熟悉汇编指令。 基本指令特点 str: store value to memory ldr: load value from memory stp: store register value to stack ldp: load stack value to register 更新寄存器的操作&#xff0c;一般结果寄存器是左操作数。 写内存的操作&#xff08;str&#xff09;&…...

微博视频无水印下载的方法

在如今的数字时代&#xff0c;社交媒体平台如微博已经成为人们分享日常生活、获取新闻和娱乐内容的重要渠道。我们时常会在刷微博时看到一些有趣的视频图片&#xff0c;或是名人的访谈&#xff0c;或是搞笑的短片&#xff0c;有时甚至是一些珍贵的历史资料。这些视频不仅内容丰…...

C语言 | Leetcode C语言题解之第390题消除游戏

题目&#xff1a; 题解&#xff1a; int lastRemaining(int n) {int a1 1;int k 0, cnt n, step 1;while (cnt > 1) {if (k % 2 0) { // 正向a1 a1 step;} else { // 反向a1 (cnt % 2 0) ? a1 : a1 step;}k;cnt cnt >> 1;step step << 1;}return …...

虚拟现实辅助工程技术助力多学科协同评估

在当今高速发展的经济环境中&#xff0c;制造业面临着多重挑战&#xff0c;包括提高产品性能、压缩设计周期、实现轻量化设计和降低成本。为了有效应对这些挑战&#xff0c;多学科协同评估成为缩短研发周期和提升研制质量的关键手段。 传统的多学科评估面临着数据孤立与融合困难…...

Java获取小程序码示例(三种小程序码)

首先我们可以看到官方文档上是有三种码的 获取小程序码 这里特别要注意的是第一种和第三种是有数量限制的&#xff0c;所以大家生成的时候记得保存&#xff0c;也不要一直瞎生成 还有一点要注意的是第一种和第二种是太阳码 第三种是方形码 好了直接上代码 这里要注意&#xff…...

【最新华为OD机试E卷-支持在线评测】分糖果(100分)-多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-E/D卷的三语言AC题解 💻 ACM金牌🏅️团队| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...