BlueRose
文章97
标签28
分类7
UAttributeSet

UAttributeSet

概述

在GameplayAbility框架中,UAttributeSet负责管理各种属性。

定义宏

在头文件中添加:

// 使用AttributeSet.h的宏
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
    GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
    GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
    GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
    GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)

参考注释可以得知,使用这些宏可以让你少写各个属性的Get、Set、Init函数。如果不使用这个宏你也可以自己实现对应的函数。

这里用到了Ue4的反射。

添加属性

再以下格式添加属性:

UPROPERTY(BlueprintReadOnly, Category = "Health")
FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS(URPGAttributeSet, Health)

重写接口

ActionRPG案例中重写了PreAttributeChange与PostGameplayEffectExecute接口。

前者会在属性被修改时调用,在案例中是为了在血量或魔法上限发生变动时,按比例调整当前血量或者魔法值。后者与GameplayEffect有关,等到编写完GameplayEffect时,再来编写。

void URPGAttributeSet::PreAttributeChange(const FGameplayAttribute & Attribute, float & NewValue)
{
    Super::PreAttributeChange(Attribute, NewValue);

    if (Attribute == GetMaxHealthAttribute())
    {
        AdjustAttributeForMaxChange(Health, MaxHealth, NewValue, GetHealthAttribute());
    }
    else if (Attribute == GetMaxManaAttribute())
    {
        AdjustAttributeForMaxChange(Mana, MaxMana, NewValue, GetManaAttribute());
    }
}

void URPGAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData & Data)
{
    Super::PostGameplayEffectExecute(Data);

}

void URPGAttributeSet::AdjustAttributeForMaxChange(FGameplayAttributeData& AffectedAttribute, const FGameplayAttributeData& MaxAttribute, float NewMaxValue, const FGameplayAttribute& AffectedAttributeProperty)
{
    UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
    const float CurrentMaxValue = MaxAttribute.GetCurrentValue();
    if (!FMath::IsNearlyEqual(CurrentMaxValue, NewMaxValue) && AbilityComp)
    {
        // Change current value to maintain the current Val / Max percent
        const float CurrentValue = AffectedAttribute.GetCurrentValue();
        float NewDelta = (CurrentMaxValue > 0.f) ? (CurrentValue * NewMaxValue / CurrentMaxValue) - CurrentValue : NewMaxValue;

        AbilityComp->ApplyModToAttributeUnsafe(AffectedAttributeProperty, EGameplayModOp::Additive, NewDelta);
    }
}

个人的使用方案

定义URPGAttributeSet作为基础属性集,里面定义通用属性。之后又定义URPGCharacterAttributeSet作为角色专用的属性集。

之后在角色类中的构造函数中挂载URPGAttributeSet对象。

UPROPERTY()
URPGAttributeSet* AttributeSet;
AttributeSet = CreateDefaultSubobject<URPGAttributeSet>(TEXT("AttributeSet"));