[UE5] GAS 애트리뷰트, Accessor

kkado·2024년 8월 21일
0

UE5

목록 보기
57/62
post-thumbnail

애트리뷰트 만들기

FGameplayAttributeData 타입의 애트리뷰트를 만들고 Replicated 변수로 등록한다.

#include "AttributeSet.h"
#include "AbilitySystemComponent.h"

UCLASS()
class AURA_API UAuraAttributeSet : public UAttributeSet
{
	GENERATED_BODY()
	
public:
	UAuraAttributeSet();
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
	
	UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category = Vital)
	FGameplayAttributeData Health;
    
	UFUNCTION()
	void OnRep_Health(const FGameplayAttributeData& OldHealth) const;
};

GetLifetimeReplicatedProps 에서 DOREPLIFETIME_CONDITION 매크로를 이용해 복제 변수 등록을 해 주는 것과 더불어, 애트리뷰트의 경우 Rep Notify 함수에서 하나의 작업을 더 해줘야 하는데 GAMEPLAYATTRIBUTE_REPNOTIFY 매크로를 사용해준다. 마찬가지로 이 애트리뷰트의 값을 다른 플레이어들에게 복제하겠다는 뜻

void UAuraAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, Health, COND_None, REPNOTIFY_Always);
}

void UAuraAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) const
{
	GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, Health, OldHealth);
}

Accessor Define

GAMEPLAYATTRIBUTE_REPNOTIFY 의 definition을 타고 올라가면 AttributeSet.h 에서 매크로가 선언된 곳을 찾아갈 수 있는데, 여기서 이런 주석 메시지를 볼 수 있다.

/**
 * This defines a set of helper functions for accessing and initializing attributes, to avoid having to manually write these functions.
 * It would creates the following functions, for attribute Health
 *
 *	static FGameplayAttribute UMyHealthSet::GetHealthAttribute();
 *	FORCEINLINE float UMyHealthSet::GetHealth() const;
 *	FORCEINLINE void UMyHealthSet::SetHealth(float NewVal);
 *	FORCEINLINE void UMyHealthSet::InitHealth(float NewVal);
 *
 * To use this in your game you can define something like this, and then add game-specific functions as necessary:
 * 
 *	#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
 *	GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
 *	GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
 *	GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
 *	GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
 * 
 *	ATTRIBUTE_ACCESSORS(UMyHealthSet, Health)
 */

대충 해석하자면 애트리뷰트에 접근하고 값을 초기화하는 데 사용되는 유용한 함수들을 제공한다는 뜻이며, static, FORCEINLINE 함수들을 자동으로 생성한 효과를 낼 수 있다는 것이다.

아래 #define으로부터 5개 라인을 복사해서 내 attribute set 헤더 파일로 가져간다.

그리고 애트리뷰트를 선언한 부분에서 아래에 ATTRIBUTE_ACCESSORS(UMyHealthSet, Health) 을 추가함으로써 간단하게 유틸 함수들을 만들 수 있다.

UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category = Vital)
FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS(UAuraAttributeSet, Health);

이제 이렇게 하면 별도의 이니셜라이저나 게터, 세터 함수를 만들지 않더라도 다음과 같은 문법으로 함수들을 사용할 수 있다.

'PropertyName' 에 애트리뷰트 명이 들간 형태로 Get, Set, Init을 사용할 수 있다. 또는 뒤에 Attribute()를 붙여서 데이터 자체를 가져올 수도 있다.

자동완성되어 사용할 수 있는 모습.

디버깅 모드에서 확인

디버깅 모드로 에디터를 실행한 후 게임에 들어가 백틱을 눌러 콘솔 입력 모드로 들어간다.
그리고 showdebug abilitysystem 이라고 치면 위 사진과 같이 여러 캐릭터들의 GAS 상태, 좌표, 태그 등을 확인할 수 있다. 아래에 AbilityTag 에서 내가 설정한 값이 반영돼있는 것을 확인할 수 있다.

profile
울면안돼 쫄면안돼 냉면됩니다

0개의 댓글