摘要:本文介绍了在虚幻引擎中创建基础属性集(UBasicAttributeSet)的实现过程,包含生命值(Health/MaxHealth)和耐力值(Stamina/MaxStamina)属性的定义。通过UCLASS宏和UPROPERTY标记实现属性的蓝图访问和网络复制功能,使用ATTRIBUTE_ACCESSORS_BASIC宏简化属性访问。文章还涉及游戏效果(GameplayEffect)的创建和应用机制,解释了添加效果使用ApplyGameplayEffectToSelf节点,而移除效果则采用RemoveActiveEffectsWithGrantedTags节点的设计逻辑:前者针对具体效果,后者关注状态清除。最后提到如何为技能添加冷却和消耗效果,并手动触发这些游戏效果。
Result Image:

Q: Read with some questions
- 为什么Gameplayability 中有cooldown 和 Costs 插槽,但是没有 StaminaRegen 插槽
GameplayAbility = 一次"行为 / 动作 / 技能"
👉 Cooldown / Cost 是"一次性行为"的规则
👉 StaminaRegen 是"持续状态",不属于 Ability 本身
2.在角色添加 耐力值回复 的功能中,为啥 添加 node 叫ApplyGameplayEffectToSelf,移除却叫 Remove Active Effects with Granted Tags?

Tip:
加的时候你知道"加谁"
删的时候你只关心"不要什么状态"
Apply:以"具体 Effect"为中心
Remove:以"状态 / 结果"为中心
- 为什么 GE_state_staminaregen stacking limit count =1
GE_State_StaminaRegen的Stacking Limit Count = 1是为了防止"重复 Apply 导致回体力叠加"
Cost 和Cooldown 不用本身就是一次性的
1. Create BasicAttributeSet C++ Class
cpp
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "BasicAttributeSet.generated.h"
/**
*
*/
UCLASS()
class GAS_API UBasicAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
UBasicAttributeSet();
// 生命值属性
UPROPERTY(BlueprintReadOnly, Category = "Attributes",ReplicatedUsing = OnRep_Health)
FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS_BASIC(UBasicAttributeSet, Health);
// 最大生命值属性
UPROPERTY(BlueprintReadOnly, Category = "Attributes",ReplicatedUsing = OnRep_MaxHealth)
FGameplayAttributeData MaxHealth;
ATTRIBUTE_ACCESSORS_BASIC(UBasicAttributeSet, MaxHealth);
// Stamina Attribute
UPROPERTY(BlueprintReadOnly, Category = "Attributes",ReplicatedUsing = OnRep_Stamina)
FGameplayAttributeData Stamina;
ATTRIBUTE_ACCESSORS_BASIC(UBasicAttributeSet, Stamina);
// MaxStamina Attribute
UPROPERTY(BlueprintReadOnly, Category = "Attributes",ReplicatedUsing = OnRep_MaxStamina)
FGameplayAttributeData MaxStamina;
ATTRIBUTE_ACCESSORS_BASIC(UBasicAttributeSet, MaxStamina);
public:
UFUNCTION()
void OnRep_Health(const FGameplayAttributeData& OldValue) const
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UBasicAttributeSet, Health, OldValue);
};
UFUNCTION()
void OnRep_MaxHealth(const FGameplayAttributeData& OldValue) const
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UBasicAttributeSet, MaxHealth, OldValue);
};
UFUNCTION()
void OnRep_Stamina(const FGameplayAttributeData& OldValue) const
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UBasicAttributeSet, Stamina, OldValue);
};
UFUNCTION()
void OnRep_MaxStamina(const FGameplayAttributeData& OldValue) const
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UBasicAttributeSet, MaxStamina, OldValue);
};
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
};
cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "BasicAttributeSet.h"
#include "Net/UnrealNetwork.h"
UBasicAttributeSet::UBasicAttributeSet()
{
// 初始化属性值
Health = 100.f;
MaxHealth = 100.f;
Stamina = 100.f;
MaxStamina = 100.f;
}
void UBasicAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION_NOTIFY(UBasicAttributeSet, Health, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UBasicAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UBasicAttributeSet, Stamina, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UBasicAttributeSet, MaxStamina, COND_None, REPNOTIFY_Always);
}
2. Create Three GameplayEffect Blueprint Class

Has Duration Cooldown 必须是 Has Duration,因为"冷却"本质就是一段时间

Instant 立刻扣除25的耐力值

Infinite 无限制,只要存在就是一直按照(1/30)秒执行一次当前Effect

3. Add Cooldown Effect & Cost Effect to Ability' Attribute

4. Manual invocation Gameplay Effects

