Unreal: Gameplay Ability System(GAS) - GamePlayCue (GC) & AttributeSet
Gameplay Cue
사운드나 이펙트등을 관리하는 표시용 시스템으로, 두가지 종류가 제공된다.
- GameplayCueNotify_Actor
- 액터 인스턴스로 생성된다.
- 액터처럼 스폰되고, 시작, 종료, 수명주기 개념이 있다.
- 수명주기와 신경써야할 것이 많아 신경쓸 게 더 있고, 오류를 피하기 위해선 더 명확한 관리를 필요로 한다.
- GameplayCueNotify_Static
- 인스턴스 없이 Class Default Object형태로 실행된다.
- GameplayCueNotify_Actor같은 오류는 덜 한 편이다.
내부에는 동작 시점에 따른 오버라이딩 가능한 함수들을 제공한다.
- OnActive - 지속형 Cue 생성
- WhileActive - 지속형 Cue 활성상태로 인식될 때
- OnExecute - 즉시 실행형 Cue, ExecuteGameplayCue에서 호출된다.
- OnRemove - 지속형 Cue 제거
- HandleGameplayCue
- OnActive, OnExecute, OnRemove를 하나로 합친 형태이다.
- Switch On EGameplayCueEvent로 OnActive, WhileActive, Executed, Removed로 분기해 사용 가능하다.
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;
};