[Unreal Engine] AttributeSet

이매·2025년 6월 5일

Unreal GAS

목록 보기
5/7

Attribute의 정의

Attribute는 캐릭터의 능력치 하나하나를 말합니다. 예를 들어:

  • Health (체력)

  • MaxHealth (최대 체력)

  • Mana (마나)

  • Strength (힘)

  • Defense (방어력)

이러한 값들은 보통 float 타입이며, GameplayEffect를 통해 여러 작업을 할 수 있습니다.


AttributeSet의 정의

AttributeSet은 여러 개의 Attribute들을 묶어서 관리하는 클래스입니다.

Owner Actor의 생성자에서 해당 AttributeSet을 생성하면 자동으로 ASC(AbilitySystemComponent)에 등록됩니다.

AbilitySystemComponent는 하나 또는 여러 개의 AttributeSet을 가질 수 있습니다. 각 방식의 장단점을 이해하고, 게임의 구조에 맞게 설계하는 것이 중요합니다.

✅ 단일 모놀리식 AttributeSet 방식

  • 하나의 큰 AttributeSet에 모든 Attribute를 정의합니다.
  • 모든 액터가 공통된 AttributeSet을 사용하고, 각자 필요한 Attribute만 활용합니다.
  • 사용하지 않는 Attribute는 무시됩니다.

예: 체력, 마나, 스태미나, 방어력 등 모든 스탯을 UMyCommonAttributeSet에 정의하고 모든 캐릭터에 적용

✅ 그룹화된 다중 AttributeSet 방식

  • 기능별로 Attribute를 나눠 별도의 AttributeSet으로 구성합니다.
  • Actor마다 필요한 AttributeSet만 선택적으로 추가합니다.

AttributeSet의 생성

AttributeSet의 생성은 현재 C++에서만 수행됩니다. 블루프린트에서는 ASC와 AttributeSet의 초기화 흐름을 완전히 제어할 수 없습니다. (5.5 version 기준)

우선 AttributeSet 클래스를 부모로 삼는 GAS_AttributeSet을 생성하겠습니다.

// GAS_AttributeSet.h
#pragma once

#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h" // AttributeSet을 사용하기 위한 헤더 파일
#include "GAS_AttributeSet.generated.h"


// Attribute를 정의하기 위한 매크로들
// UAttributeSet에 정의되어 있는 매크로로 Getter, setter, initter 등을 자동으로 생성합니다.
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
	GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)

UCLASS()
class GASTEMPLATE_API UGAS_AttributeSet : public UAttributeSet
{
	GENERATED_BODY()
	
public:

	/*
	 *	속성(Attribute)에 어떤 수정이 일어나기 직전에 호출됩니다. 이 함수는 PreAttributeModify/PostAttributeModify보다 더 하위 레벨에서 동작합니다.
	 *	여기서는 추가적인 컨텍스트가 제공되지 않으며, 실행된 효과, 지속 효과, 효과 제거, 면역 적용, 스택 규칙 변경 등 어떤 것이든 이 함수를 트리거할 수 있습니다.
	 *	이 함수의 목적은 "Health = Clamp(Health, 0, MaxHealth)"와 같이 값을 강제로 제한하는 것이며, "데미지가 적용되면 추가로 무언가를 트리거한다"와 같은 동작을 구현하는 곳이 아닙니다.
	 *
	 *	NewValue는 변경 가능한 참조(mutable reference)이므로, 새로 적용되는 값을 이 함수 내에서 제한(clamp)할 수 있습니다.
	 */
	virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;

	/* 속성(Attribute)에 어떤 수정이 발생한 직후에 호출됩니다. */
	virtual void PostAttributeChange(const FGameplayAttribute& Attribute, float OldValue, float NewValue) override;


	// 속성(Attribute) 정의
	UPROPERTY(BlueprintReadOnly, Category = "Attribute")
	FGameplayAttributeData Health;
	ATTRIBUTE_ACCESSORS(UGAS_AttributeSet, Health) // Health 속성에 대한 Getter, Setter, Initter를 자동으로 생성합니다.

};
// GAS_AttributeSet.cpp
#include "GAS/Attributes/GAS_AttributeSet.h"

void UGAS_AttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
{
	// 여기서 속성(Attribute)의 값을 제한하거나 조정할 수 있습니다.
}

void UGAS_AttributeSet::PostAttributeChange(const FGameplayAttribute& Attribute, float OldValue, float NewValue)
{
	// 속성(Attribute)의 값이 변경된 후에 추가적인 작업을 수행할 수 있습니다.
}

AttributeSet에서 Attribute를 생성하려면 3가지의 기본적인 작업이 필요합니다

  1. #include "AbilitySystemComponent.h" 헤더 추가
  2. #define ATTRIBUTE_ACCESSORS 매크로 추가
  3. Attribute 변수 생성

이렇게 생성된 Attribute는 이제 GAS Framework내에서 자유롭게 사용하여 다양한 값들을 사용할 수 있게 됩니다.

또한 생성된 Attribute는 Unreal Engine에서 제공하는 멀티플레이에서의 프로퍼티 복제 시스템과 매우 유사한 방식으로 사용 가능합니다.
이에 대해서는 추가적인 작업이 필요하지만, 이번에는 다루지 않겠습니다.

액터에 AttributeSet 적용하기

이제 액터에 생성한 AttributeSet을 적용시켜보겠습니다.

현재(5.5 version 혹은 그 이하 버전)는 ASC가 부착된 액터에 AttributeSet을 사용하기 위해서는 C++에서만 생성이 가능합니다.

// YourCharacter.h

...

class AGASTemplateCharacter : public ACharacter, public IAbilitySystemInterface
{
	GENERATED_BODY()
    
    ...
    
    /** AttributeSet */
	UPROPERTY()
	TObjectPtr<class UGAS_AttributeSet> AttributeSet;

AttributeSet 초기화하기

적용시킨 AttributeSet을 초기화하는 방식에는 여러 가지가 있습니다.

  • AttributeSet 생성자에서 초기화(C++코드만 해당)
  • PostInitializeComponents/BeginPlay에서 초기화(코드만 해당)
  • BeginPlay에서 Instant GameplayEffect 적용
  • DataTable 혹은 CurveTables 이용

그 중에서도 여기에서는 DataTable 혹은 CurveTables을 이용하는 방식에 대해 설명하겠습니다.

DataTable 이용 방법

브라우저에서 우클릭을 한 뒤,

기타 - 데이터테이블 - 행구조(AttributeMetaData) 선택

을 한 후 DT_InitAttributeSet을 생성합니다.

이후 DataTable의 값의 이름을 "AttributeSet Name"."Attribute Name"과 같은 형식으로 만들고 초기화할 값과 최소 최대값을 지정해줍니다.

이렇게 생성된 데이터 테이블은 블루프린트에서 액터의 Ability System Component - Attribute Test 항목에 넣어 사용할 수 있게 됩니다.

이후 게임을 시작해보면 디버깅 창에 다음과 같이 Attribute가 적용된 것을 볼 수 있습니다.

이제 이렇게 생성된 Attribute는 Gameplay Ability와 Gameplay Effect 등을 통해 자유롭게 변경이 가능합니다.

다음 포스팅에서는 생성된 Attribute를 가지고 Gameplay Effect를 다루어 보겠습니다.

profile
언리얼 엔진 주니어(신입) 개발자 | 소설 쓰는 취준 개발자

0개의 댓글