PART 2 - 강의 1/3
AttributeSet 구조
FGameplayAttributeData와 ATTRIBUTE_ACCESSORS 매크로
01
AttributeSet 기본 구조
어트리뷰트 정의와 복제 설정
기본 AttributeSet 클래스
UCLASS()
class MYGAME_API UMyAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
UMyAttributeSet();
// 복제 설정
virtual void GetLifetimeReplicatedProps(
TArray<FLifetimeProperty>& OutLifetimeProps) const override;
// 어트리뷰트 정의
UPROPERTY(BlueprintReadOnly, Category = "Health",
ReplicatedUsing = OnRep_Health)
FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS(UMyAttributeSet, Health)
UPROPERTY(BlueprintReadOnly, Category = "Health",
ReplicatedUsing = OnRep_MaxHealth)
FGameplayAttributeData MaxHealth;
ATTRIBUTE_ACCESSORS(UMyAttributeSet, MaxHealth)
protected:
UFUNCTION()
virtual void OnRep_Health(const FGameplayAttributeData& OldHealth);
UFUNCTION()
virtual void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth);
};
02
ATTRIBUTE_ACCESSORS 매크로
어트리뷰트 접근자 자동 생성
ATTRIBUTE_ACCESSORS 매크로 정의
// ATTRIBUTE_ACCESSORS 매크로가 생성하는 함수들
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
// 각각 생성되는 함수:
// 1. static FGameplayAttribute GetHealthAttribute()
// - GameplayEffect에서 어트리뷰트 참조용
// 2. float GetHealth() const
// - 현재 값 조회
// 3. void SetHealth(float NewVal)
// - 값 직접 설정 (GE 통해서만 사용 권장)
// 4. void InitHealth(float NewVal)
// - 초기화 시 사용 (BaseValue와 CurrentValue 모두 설정)
사용 권장사항
SetHealth()는 직접 호출하지 말고 GameplayEffect를 통해 값을 변경하세요. 직접 변경은 네트워크 복제, 예측, 콜백 처리를 건너뛰어 버그를 유발할 수 있습니다.
03
다중 AttributeSet 관리
역할별 AttributeSet 분리
다중 AttributeSet 구성
// 기본 체력 세트
UCLASS()
class UHealthAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health)
FGameplayAttributeData Health;
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxHealth)
FGameplayAttributeData MaxHealth;
};
// 전투 스탯 세트
UCLASS()
class UCombatAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_AttackPower)
FGameplayAttributeData AttackPower;
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Defense)
FGameplayAttributeData Defense;
};
// 캐릭터에서 다중 세트 사용
void AMyCharacter::InitializeAttributes()
{
// ASC는 각 클래스당 하나의 AttributeSet만 가질 수 있음
HealthSet = NewObject<UHealthAttributeSet>(this);
CombatSet = NewObject<UCombatAttributeSet>(this);
// ASC에 등록
AbilitySystemComponent->AddAttributeSetSubobject(HealthSet);
AbilitySystemComponent->AddAttributeSetSubobject(CombatSet);
}
클래스 중복 불가
ASC는 같은 클래스의 AttributeSet을 여러 개 가질 수 없습니다. 다른 역할의 어트리뷰트는 별도 클래스로 분리하세요.
04
BaseValue vs CurrentValue
영구 값과 버프 적용 후 값
| 구분 | BaseValue | CurrentValue |
|---|---|---|
| 정의 | 영구적인 기본 값 | 모든 Modifier 적용 후 최종 값 |
| 수정 방법 | Instant GE | Duration/Infinite GE |
| 예시 | 레벨업으로 최대체력 +10 | 버프로 공격력 20% 증가 |
| 지속성 | 영구 지속 | GE 종료 시 원래 값 복구 |
값 계산 공식
// Modifier 연산 순서
// CurrentValue = (BaseValue + SumOfAdditive) * ProductOfMultiplicative
// 예시: BaseValue = 100, Additive +20, Multiplicative *1.5
// CurrentValue = (100 + 20) * 1.5 = 180
SUMMARY
핵심 요약
- FGameplayAttributeData로 어트리뷰트 정의
- ATTRIBUTE_ACCESSORS 매크로로 Getter/Setter/Init 자동 생성
- ReplicatedUsing으로 클라이언트 동기화 콜백 지정
- 역할별 다중 AttributeSet 분리 가능 (단, 클래스 중복 불가)
- BaseValue: 영구 값 (Instant GE), CurrentValue: 버프 적용 값
PRACTICE
도전 과제
배운 내용을 직접 실습해보세요
실습 1: AttributeSet 생성
UAttributeSet을 상속하여 Health, MaxHealth, AttackPower를 GAMEPLAYATTRIBUTE_PROPERTY_GETTER/SETTER 매크로와 함께 선언하세요. GetLifetimeReplicatedProps에서 복제를 설정하세요.
실습 2: 복수 AttributeSet 사용
CombatAttributeSet과 MovementAttributeSet을 별도로 만들고 같은 ASC에 등록하세요. 각각의 어트리뷰트가 독립적으로 수정되는지 테스트하세요.
심화 과제
undefined