AttributeSet是GAS系统中存放属性的地方
比如生命值、魔力值、攻击力、防御力
1.ATTRIBUTE_ACCESSORS宏
由于角色的属性众多 并且每个属性都需要Getter和Setter这种辅助函数
为了减少程序员重复操作 虚幻5提供了ATTRIBUTE_ACCESSORS宏
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
将这段代码放在类之前
每次创建属性之后 添加如下语句
ATTRIBUTE_ACCESSORS(类名, 属性名)
之后会自动创建下列函数(以属性名Health为例)
static FGameplayAttribute UMyHealthSet::GetHealthAttribute();
FORCEINLINE float UMyHealthSet::GetHealth() const;
FORCEINLINE void UMyHealthSet::SetHealth(float NewVal);
FORCEINLINE void UMyHealthSet::InitHealth(float NewVal);
2.示例
//.h
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
UCLASS()
class WARRIOR_API UWarriorAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
UWarriorAttributeSet();
virtual void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData &Data) override;
UPROPERTY(BlueprintReadOnly,Category="Health")
FGameplayAttributeData CurrentHealth;
ATTRIBUTE_ACCESSORS(UWarriorAttributeSet, CurrentHealth)
UPROPERTY(BlueprintReadOnly, Category = "Health")
FGameplayAttributeData MaxHealth;
ATTRIBUTE_ACCESSORS(UWarriorAttributeSet, MaxHealth)
}
//.cpp
UWarriorAttributeSet::UWarriorAttributeSet()
{
InitCurrentHealth(1.0f);
InitMaxHealth(1.0f);
}
void UWarriorAttributeSet::PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData &Data)
{
...
}
//其他.cpp
GetCurrentHealth();
SetCurrentHealth();
GetCurrentHealthAttribute();
3.调试指令
~键调出控制台
输入指令showdebug abilitysystem 回车就能看到角色的属性值
在DefaultGame.ini中添加如下代码
[/Script/GameplayAbilities.AbilitySystemGlobals]
bUseDebugTargetFromHud = true;
按page down/page up 键 即可切换角色
以下四个回调函数按照顺序依次执行
4.PreGameplayEffectExecute
UAttributeSet 类的一个关键虚函数,主要用于在 GameplayEffect (GE) 修改属性之前执行逻辑验证或干预。
virtual bool PreGameplayEffectExecute(
struct FGameplayEffectModCallbackData &Data
)
- 触发时机:
当 GE 通过 InternalExecuteMod 方法尝试修改属性值时,PreGameplayEffectExecute 会在属性实际修改前被调用。 - 主要功能:
条件验证:可在此函数内检查属性修改的合法性(如是否满足某些条件),通过返回 true 或 false 决定是否允许后续修改。若返回 false,则 GE 的修改操作会被中止。
数据预处理:可对即将生效的 GE 参数(如伤害值、增益值)进行动态调整(例如根据角色状态修正伤害数值)。 - 返回值:
若返回 true:GE 的修改操作会继续执行,随后调用 PostGameplayEffectExecute 处理后续逻辑。
若返回 false:属性修改流程会被终止,PostGameplayEffectExecute 也不会被触发 - 参数: Data中包含如下关键信息
- EffectSpec:当前生效的 GameplayEffectSpec。
- EvaluatedData:属性修改的最终结果(含目标属性、修改量及计算方式)。
- Attribute:当前修改的属性
- Magnitude:具体的修改量
- ModifierOp:计算方式 GameplayEffect中指定的操作符
- Target:目标角色的 AbilitySystemComponent (ASC)
5.PreAttributeChange
UAttributeSet 类的核心回调函数,用于在 属性值(Attribute) 被修改前进行逻辑干预
virtual void PreAttributeChange(
const FGameplayAttribute& Attribute,
float& NewValue
)
- 作用:
在属性值被写入前触发,允许开发者对即将修改的数值进行动态调整或强制约束(如限制生命值在 0~MaxHealth 之间)。
不触发游戏内的副作用(如受击动画、UI 更新),仅处理数值本身。 - 参数:
Attribute:当前被修改的属性(如 Health),可通过 GetHealthAttribute() 等方法进行匹配。
NewValue:即将被赋予的新值,可直接修改此参数以调整最终生效的数值。
6.PostAttributeChange
UAttributeSet 类的核心回调函数,用于在 属性值(Attribute) 被修改后执行逻辑
virtual void PostAttributeChange(
const FGameplayAttribute& Attribute,
float OldValue,
float NewValue
)
- 作用:
在属性值完成修改后被调用,用于处理与数值变化相关的 副作用逻辑(如播放受击动画、更新 UI 或触发死亡检测)。
提供旧值(OldValue)和新值(NewValue),支持基于差值执行逻辑(如伤害量计算)。 - 参数:
Attribute:被修改的属性(如 Health),通过 GetHealthAttribute() 等方法匹配。
OldValue 与 NewValue:修改前后的数值,用于差值计算或状态判断。
7.PostGameplayEffectExecute
UAttributeSet 类的关键虚函数,用于在 GameplayEffect (GE) 成功修改属性后执行逻辑响应。
virtual void PostGameplayEffectExecute(
const struct FGameplayEffectModCallbackData &Data
)
- 触发条件:
仅在 GE 通过 PreGameplayEffectExecute 验证(返回 true)且属性修改完成后触发。 - 主要作用:
副作用处理: 根据属性变化触发事件(如生命值归零时触发死亡逻辑)。
状态同步: 更新角色状态(如广播属性变化事件或同步 UI 显示)。
**复杂逻辑扩展:**基于修改后的属性值触发其他技能或效果(如伤害反弹、治疗特效播放) - 参数: 同PreGameplayEffectExecute