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

UE 5 GAS 在项目中处理AttributeSet相关

这一篇文章是个人的实战经验记录,如果对基础性的内容不了解的,可以看我前面一篇文章对基础的概念以及内容的讲解。

设置AttributeSet

使用GAS之前,首先需要设置参数集AS,这个是用于同步的一些参数,至于如何设置GAS,我之前的文章里面有讲,这里不赘述。
每个Attribute其实包含两个值 Base Value和Current Value。Base Value是在GE里面Instant设置属性时被修改的值,而Current Value是在GE的Infinite(永久修改)和Has Duration(具有时效性修改)时修改的,目的就是为了时效失效以后,能够将值的结果修改回去。当然获取值时都是获取的Current Value,如果没有时效性的影响,Base Value和Current Value值也是相等的。
AS里面主要还是为了创建一些值,并且由ASC调用GE去修改里面的值,但是这个类只能在C++里面去定义。
在这里插入图片描述
上面是我在AS里面定义的两个生命相关的值,以及覆盖的两个函数回调。
在这里插入图片描述
PreAttributeChange 主要是为了触发一个值的最大值被修改后,它的值也会按比例进行修改
在这里插入图片描述
AdjustAttributeForMaxChange 就是为了实现这个效果的函数,这个也是从ActionRPG的项目里面抄过来的。
在这里插入图片描述
PostGameplayEffectExecute 就是Base Value改变后触发的,我们可以在这个函数里面比如限制血量不会超过最大血量的值,也不会小于0的情况。

初始化Attribute

创建好了AS,接着要在角色身上使用并且初始化AS里面一些值,这里有三种方法:

  1. 第一种方法也不算方法,其实就是在AS类里面给它设置默认值
    在这里插入图片描述
    这是设置以后也算是初始化了相关属性的一些值。
    在这里插入图片描述
    我们还需要在OwnerActor里面进行初始化,需要在实例化ASC后面创建即可。这样我们就可以在ASC中去获取AS的值了。

  2. 第二种方法当然就是官方推荐的使用GE去初始化
    在这里插入图片描述
    创建一个GE,然后Duration Policy设置为Instant(直接修改Base Value),然后设置好需要修改的Attribute,Modifier Op设置为Override(覆盖),然后在下面的设置固定数值,就可以实现重新设置,只需要设置每个就可以实现覆盖。
    在这里插入图片描述
    这里有个小细节,就是初始化时,推荐先修改最大值,然后再修改默认值,因为在C++里面,我们有个按比例进行修改默认值的,如果你先修改Health然后再修改MaxHealth,它会按比例放大的,然后再直接获取值会出现问题,所以我先设置的最大值,然后再设置就没这样的问题了。
    在这里插入图片描述
    设置完成以后,使用ApplyGameplayEffectToSelf节点,去设置即可。

  3. 使用DataTable设置默认值
    在这里插入图片描述
    这个需要开启在蓝图内读写ASC
    在这里插入图片描述
    然后ASC细节里面会有一项AttributeTest,里面可以创建多个数组,代表可以初始化多个AS。Attributes选择AS的类,DefaultStartingTable则是选择创建的DataTable。
    在这里插入图片描述
    创建DataTable的时候,需要选择AttributeMetaData
    在这里插入图片描述
    行命名,要和在GE里面设置的命名保持一致,设置值时,就BaseValue有用,其它值估计是为了以后版本更新时使用,现在还没啥用。

获取AttributeSet的数据

在这里插入图片描述
可以从ASC去获取属性的Base Value
在这里插入图片描述
可以从ASC中获取Current Value

我们还可以通过扩展c++接口来实现获取
在这里插入图片描述
比如在它的OwnerActor类里面增加获取属性的方法,其实就是返回AttributeSet的相关属性

还有一种就是使用AbilityTask实现监听接口,需要创建C++类来实现,这里我也是直接从官方文档案例里面扒的,把代码列出来。

AT_AttributeChanged.h

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "AbilitySystemComponent.h"
#include "AT_AttributeChanged.generated.h"DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnAttributeChanged, FGameplayAttribute, Attribute, float, NewValue, float, OldValue);/*** Blueprint node to automatically register a listener for all attribute changes in an AbilitySystemComponent.* Useful to use in UI.*/
UCLASS(BlueprintType, meta = (ExposedAsyncProxy = AsyncTask))
class SURVIVALALONE_API UAT_AttributeChanged : public UBlueprintAsyncActionBase
{GENERATED_BODY()public:UPROPERTY(BlueprintAssignable)FOnAttributeChanged OnAttributeChanged;// Listens for an attribute changing.UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))static UAT_AttributeChanged* ListenForAttributeChange(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAttribute Attribute);// Listens for an attribute changing.// Version that takes in an array of Attributes. Check the Attribute output for which Attribute changed.UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))static UAT_AttributeChanged* ListenForAttributesChange(UAbilitySystemComponent* AbilitySystemComponent, TArray<FGameplayAttribute> Attributes);// You must call this function manually when you want the AsyncTask to end.// For UMG Widgets, you would call it in the Widget's Destruct event.UFUNCTION(BlueprintCallable)void EndTask();protected:UPROPERTY()UAbilitySystemComponent* ASC;FGameplayAttribute AttributeToListenFor;TArray<FGameplayAttribute> AttributesToListenFor;void AttributeChanged(const FOnAttributeChangeData& Data);
};

AT_AttributeChanged.cpp

// Fill out your copyright notice in the Description page of Project Settings.#include "AT_AttributeChanged.h"UAT_AttributeChanged *UAT_AttributeChanged::ListenForAttributeChange(UAbilitySystemComponent *AbilitySystemComponent, FGameplayAttribute Attribute)
{UAT_AttributeChanged *WaitForAttributeChangedTask = NewObject<UAT_AttributeChanged>();WaitForAttributeChangedTask->ASC = AbilitySystemComponent;WaitForAttributeChangedTask->AttributeToListenFor = Attribute;if (!IsValid(AbilitySystemComponent) || !Attribute.IsValid()){WaitForAttributeChangedTask->RemoveFromRoot();return nullptr;}AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(Attribute).AddUObject(WaitForAttributeChangedTask, &UAT_AttributeChanged::AttributeChanged);return WaitForAttributeChangedTask;
}UAT_AttributeChanged *UAT_AttributeChanged::ListenForAttributesChange(UAbilitySystemComponent *AbilitySystemComponent, TArray<FGameplayAttribute> Attributes)
{UAT_AttributeChanged *WaitForAttributeChangedTask = NewObject<UAT_AttributeChanged>();WaitForAttributeChangedTask->ASC = AbilitySystemComponent;WaitForAttributeChangedTask->AttributesToListenFor = Attributes;if (!IsValid(AbilitySystemComponent) || Attributes.Num() < 1){WaitForAttributeChangedTask->RemoveFromRoot();return nullptr;}for (FGameplayAttribute Attribute : Attributes){AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(Attribute).AddUObject(WaitForAttributeChangedTask, &UAT_AttributeChanged::AttributeChanged);}return WaitForAttributeChangedTask;
}void UAT_AttributeChanged::EndTask()
{if (IsValid(ASC)){ASC->GetGameplayAttributeValueChangeDelegate(AttributeToListenFor).RemoveAll(this);for (FGameplayAttribute Attribute : AttributesToListenFor){ASC->GetGameplayAttributeValueChangeDelegate(Attribute).RemoveAll(this);}}SetReadyToDestroy();MarkAsGarbage();
}void UAT_AttributeChanged::AttributeChanged(const FOnAttributeChangeData &Data)
{OnAttributeChanged.Broadcast(Data.Attribute, Data.NewValue, Data.OldValue);
}

类实现了以后,我们可以使用里面的两个方法:
在这里插入图片描述
Listen for Attribute Change 可以监听一个属性的变动,返回了当前监听实例,以及变动后的回调,还有之前的值,变化后的值,如果值发生改变,就会触发OnAttributeChanged执行,只需要后面执行,每次数值改变,都会触发执行。
在这里插入图片描述
Listen for Attribute Change可以传入一个数组,获取多个属性的变动然后可以通过Attribute返回值判断是哪个属性
在这里插入图片描述
取消监听,那么记得调用End Task,一般在UI里面使用,可以在创建UI的时候绑定,然后把绑定的Task设置为变量,销毁的时候End Task即可。

设置AttributeSet的值

在GAS系统中,修改AttributeSet的值,需要使用GE去实现
在这里插入图片描述
前面在初始化的时候,也讲了相应的配置。如果上面的值是Instant,那么这个GE被调用的时候,血量的值会瞬间掉1点。

接下来,介绍几个会在项目中使用到的场景。

持续掉血,每秒掉多少血量

在这里插入图片描述
使用Has Duration,下面设置持续时间,在Period设置每过多少秒触发一次,Execute Periodic Effect on Application 意思为添加时是否触发一次。
在这里插入图片描述
最简单的就是调用一下就行了,一般这个需要在GA里面去触发的,这一篇不包括GA相关。

根据等级设置血量加成

先创建一个CSV,可以先创建Excel文件,转csv
在这里插入图片描述
设置好文件以后
在这里插入图片描述
创建一个曲线表格
在这里插入图片描述
选择上面导入键,可以将csv文件导入,Row是作为值的名称,使用时需要选择哪个Row,而数字则代表当前的技能等级。
在这里插入图片描述
这里因为是加成,所以,运算修改为相乘,而ScalableFloatMagnitude的数值是从曲线表格里面获取到的值和此值相乘为最终的值。这个值再与现在的MaxHealth相乘得到了变化后的值。
后面设置了曲线表格,然后选择Row,然后就可以预览相应的值,这个预览的值是在将GE附加到ASC上面的时候设置。
在这里插入图片描述
在附加的时候,我们可以设置Level等级,就是曲线表格里面的那个数值。

http://www.lryc.cn/news/119148.html

相关文章:

  • JDBC数据库连接
  • gitee分支合并
  • Python小白入门:文件、异常处理和json格式存储数据
  • 16bit、8 通道、500kSPS、 SAR 型 ADC——MS5188N
  • Chapter 12: Regular expressions | Python for Everybody 讲义笔记_En
  • Android javaMail mergeDebugJavaResource FAILED解决
  • 【ArcGIS Pro二次开发】(57):地图系列
  • 秋招打卡015(20230811)
  • 如何使用Word转PDF转换器在线工具?在线Word转PDF使用方法
  • 自然语言处理从入门到应用——LangChain:记忆(Memory)-[记忆的类型Ⅰ]
  • Camunda 7.x 系列【7】Spring Boot 集成 Camunda 7.19
  • 24华东交通软件工程837考研题库
  • nginx 以及nginx优化
  • cesium学习记录04-坐标系
  • P5737 【深基7.例3】闰年展示
  • Nacos的安装使用教程Linux
  • 数据结构-学习
  • 【MFC】05.MFC六大机制:程序启动机制-笔记
  • Von Maur, Inc EDI 需求分析
  • [深度学习入门]PyTorch深度学习[Numpy基础](上)
  • Excel vost 实现照光灯效果
  • IntelliJ中文乱码问题
  • 【C++】红黑树模拟实现插入功能(包含旋转和变色)
  • Pads输出器件坐标文件时,如何更改器件坐标精度
  • Vuejs3父组传值给子组件
  • 竞赛项目 深度学习的智能中文对话问答机器人
  • 【剑指 の 精选】热门状态机 DP 运用题
  • 自动化实践-全量Json对比在技改需求提效实践
  • 【Matlab】PSO优化(单隐层)BP神经网络
  • 创建型模式-原型模式