## 概述 在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(TEXT("AttributeSet")); ```