🎮 UBFPlayerAttributeSet.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 BOSSFIGHT_API UBFPlayerAttributeSet : public UAttributeSet { GENERATED_BODY() public: UBFPlayerAttributeSet(); virtual void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data)override; UPROPERTY(BlueprintReadOnly, Category = "Stamina") FGameplayAttributeData CurrentSP; ATTRIBUTE_ACCESSORS(UBFPlayerAttributeSet, CurrentSP) UPROPERTY(BlueprintReadOnly, Category = "Stamina") FGameplayAttributeData MaxSP; ATTRIBUTE_ACCESSORS(UBFPlayerAttributeSet, MaxSP) UPROPERTY(BlueprintReadOnly, Category = "Weapon") FGameplayAttributeData WeaponGage; ATTRIBUTE_ACCESSORS(UBFPlayerAttributeSet, WeaponGage) UPROPERTY(BlueprintReadOnly, Category = "Weapon") FGameplayAttributeData WeaponCount; ATTRIBUTE_ACCESSORS(UBFPlayerAttributeSet, WeaponCount) UPROPERTY(BlueprintReadOnly, Category = "Weapon") FGameplayAttributeData ShieldGage; ATTRIBUTE_ACCESSORS(UBFPlayerAttributeSet, ShieldGage) };🎮 UBFPlayerAttributeSet.cpp
UBFPlayerAttributeSet::UBFPlayerAttributeSet() { InitCurrentSP(0.0f); InitMaxSP(0.0f); InitWeaponGage(0.0f); InitWeaponCount(0.0f); InitShieldGage(0.0f); } void UBFPlayerAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) { if (Data.EvaluatedData.Attribute == GetCurrentSPAttribute()) { const float NewCurrentSP = FMath::Clamp(GetCurrentSP(), 0.0f, GetMaxSP()); SetCurrentSP(NewCurrentSP); } if (Data.EvaluatedData.Attribute == GetMaxSPAttribute()) { const float NewMaxSP = FMath::Clamp(GetMaxSP(), 0.0f, 200.0f); SetMaxSP(NewMaxSP); } if (Data.EvaluatedData.Attribute == GetWeaponCountAttribute()) { const int NewWeaponCount = FMath::Clamp(GetWeaponCount(), 0.0f, 3.0f); SetWeaponCount(NewWeaponCount); } if (Data.EvaluatedData.Attribute == GetWeaponGageAttribute()) { const float NewWeaponGage = FMath::Clamp(GetWeaponGage(), 0.0f, 100.0f); SetWeaponGage(NewWeaponGage); } if (Data.EvaluatedData.Attribute == GetShieldGageAttribute()) { const float NewShieldGage = FMath::Clamp(GetShieldGage(), 0.0f, 100.0f); SetShieldGage(NewShieldGage); } }필요한 스탯을 정리하고, PostGameplayEffectExecute()함수에서 값을 Clamp해주는 기능을 추가 해주었다.
🎮 ABFPlayerCharacter.h
UCLASS() class BOSSFIGHT_API ABFPlayerCharacter : public ABFBaseCharacter { GENERATED_BODY() //중략 #pragma region PlayerAttributeSet UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AbilitySystem", meta = (AllowPrivateAccess = "true")) UBFPlayerAttributeSet* BFPlayerAttributeSet; #pragma endregion };🎮 ABFPlayerCharacter.cpp
ABFPlayerCharacter::ABFPlayerCharacter() { // 중략 BFPlayerAttributeSet = CreateDefaultSubobject<UBFPlayerAttributeSet>(TEXT("BFPlayerAttributeSet")); }Attribute는 CreateDefaultSubobject를통해 생성 해주면 AbilityComponent가 자동으로 적용 시켜주기 때문에 PlayerCharacter의 생성자에서 생성해주는 것으로 구현 하였다.







