Post

Unreal: Gameplay Ability System(GAS) - GamePlayCue (GC) & AttributeSet

Unreal: Gameplay Ability System(GAS) - GamePlayCue (GC) & AttributeSet

Gameplay Cue

사운드나 이펙트등을 관리하는 표시용 시스템으로, 두가지 종류가 제공된다.

  • GameplayCueNotify_Actor
    • 액터 인스턴스로 생성된다.
    • 액터처럼 스폰되고, 시작, 종료, 수명주기 개념이 있다.
    • 수명주기와 신경써야할 것이 많아 신경쓸 게 더 있고, 오류를 피하기 위해선 더 명확한 관리를 필요로 한다.
  • GameplayCueNotify_Static
    • 인스턴스 없이 Class Default Object형태로 실행된다.
    • GameplayCueNotify_Actor같은 오류는 덜 한 편이다.

image 내부에는 동작 시점에 따른 오버라이딩 가능한 함수들을 제공한다.

  • OnActive - 지속형 Cue 생성
  • WhileActive - 지속형 Cue 활성상태로 인식될 때
  • OnExecute - 즉시 실행형 Cue, ExecuteGameplayCue에서 호출된다.
  • OnRemove - 지속형 Cue 제거
  • HandleGameplayCue
    • OnActive, OnExecute, OnRemove를 하나로 합친 형태이다.
    • Switch On EGameplayCueEvent로 OnActive, WhileActive, Executed, Removed로 분기해 사용 가능하다.

image Gameplay Cue는 GameplayCue.로 시작하는 독립적인 태그를 Gameplay Cue Tage에서 지정해 사용해야한다. GA에서는 태그로 Gameplay Cue 불러와 사용할 수 있다.

  • 붙였다 떼는 방식
    • AddGameplayCueOnOwner - RemoveGameplayCueFromOwner
    • OnActive, WhileActive, OnRemove가 호출된다.
    • 시작과 끝나는 시점의 효과를 다르게 하는등의 사용에 적합하다.
  • 단발성으로 실행하는 방식
    • ExecuteGameplayCueOnOwner
    • OnExecute만 실행한다.
    • 한번만 효과 재생하고 끝나는 방식에 적합하다.

AttributeSet

스텟을 관리해주는 클래스이다. AttributeSet을 상속받아 만들 수 있다.

1
2
3
4
5
6
7
#include "AttributeSet.h"
//...
UCLASS()
class TESTPROJECT_API UTestAttributeSetBase : public UAttributeSet
{
	//...
};

각 스텟은 FGameplayAttributeData에 저장할 수 있다. AttributeSet에서 사용하는 데이터 저장용 구조체로, float 형태로 체력, 마나등 각종 수치를 저장하는데 사용할 수 있다. 기본적으론 float의 자료형만 제공되는데 내부에선 BaseValue와 CurrentValue로 나뉘어 GameplayEffect로 수정되는 값과 돌아가야할 원본 값을 저장해놓는 용도로 사용된다. Vector같은 자료형을 표현하고 싶다면 각 성분별로 쪼개서 저장해야한다.

1
2
3
public:
	UPROPERTY()
	FGameplayAttributeData HP;

생성된 속성/수치들은 AttributeSet과 함께 제공되는 메크로를 통해 getter,setter같은 기본적인 함수를 자동 생성할 수 있다. UAttributeSet 클래스로 가보면 주석과 함께 잘 설명되어 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
UCLASS()
class TESTPROJECT_API UTestAttributeSetBase : public UAttributeSet
{
public:
	UPROPERTY(BlueprintReadOnly, Category = "Attributes")
	FGameplayAttributeData HP;
	ATTRIBUTE_ACCESSORS(UTestAttributeSetBase, HP);
};

Attribute 접근용 매크로를 정의해두면 GetHP, SetHP, InitHP, GetHPAttribute 같은 접근 함수를 생성할 수 있다. Setter가 제공되긴 하지만, GameplayEffect를 이용해 변경/수정을 제어하도록 설계되어 있기에 사용이 권장되진 않으며, 생성 이후에 변경은 내부적으로만 setter를 사용하고 외부에선 GameplayEffect를 사용함이 바람직하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
UGASAttributeSetBase::UGASAttributeSetBase()
{
	InitHP(100.f);

//	게임플레이 도중엔 AS에서 변경 금지,GameplayEffect를 이용해 변경
//	//HP 얻기
//	GetHP();
//
//	//HP 설정
//	SetHP(150.f);
//	
//	//HP 포인터 얻기, 같은 값을 가리키는지 확인하는등의 용도로 사용 가능하다.
//	GetHPAttribute();
}

속성의 변경 과정에서 전후로 입력검사나 추가 로직 호출등을 위해 이벤트 함수를 활용할 수 있다. 크게 GameplayEffect 호출 전후, 속성의 변경 전후가 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
UCLASS()
class TESTPROJECT_API UTestAttributeSetBase : public UAttributeSet
{
	GENERATED_BODY()

	
public:
	ATTRIBUTE_ACCESSORS(UGASAttributeSetBase, HP);
	
	UTestAttributeSetBase ();

	UPROPERTY()
	FGameplayAttributeData HP;

	//호출 순서:
	//PreGameplayEffectExecute -> PreAttributeChange -> PostAttributeChange -> PostGameplayEffectExecute 
	
	//명령 받은 후
	virtual bool PreGameplayEffectExecute(struct FGameplayEffectModCallbackData& Data) override;
	
	//명령 실행 후
	virtual void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data) override;

	//속성 변경 전
	virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)  override;
	
	//속성 변경 후
	virtual void PostAttributeChange(const FGameplayAttribute& Attribute, float OldValue, float NewValue) override;
};
This post is licensed under CC BY 4.0 by the author.