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