FGameplayTag
- GameplayTagManager에 등록되어 있는 계층 구조를 가지는 이름
- 오브젝트의 상태를 분류하고 설명하는데 유용하게 사용되는 구조체
- 오브젝트가 어떤 태그를 들고 있는지, 없는지에 따라 현재 상태를 나타낼 수 있음. (ex. stun)
- 기존에는 캐릭터의 상태를 bool이나 enum으로 처리하던 것을 GameplayTags로 대체할 수 있고, 이로 인해 객체에 특정 GameplayTags가 있는지 여부를 확인하며 논리 구조를 세울 수 있습니다.
- 오브젝트에 태그를 부여할 때는 GAS와 상호작용을 할 수 있도록 AbilitySystemComponent에 부여하는 것이 일반적입니다.
- UAbilitySystemComponent는 IGameplayTagAssetInterface를 구현하여 GameplayTags에 엑세스 하는 함수들을 제공합니다.
- GameplayTag는 DefaultGAmeplayTags.ini에 정의되어 있습니다.
- 언리얼 엔진(UE5 기준)에서는 DefaultgGameplayTags.ini를 직접 수정하는 것이 아닌, 에디터 내의 Project Setting→Project→GameplayTags에서 Create, rename, search for reference, delete를 할 수 있도록 제공하고 있습니다.
- Search for References를 사용하면, Reference Viewer와 비슷한 형태의 그래프 에디터가 나타나며, 그 안에서 해당 GameplayTag를 사용하고 있는 Asset 목록을 확인할 수 있습니다.
- 그러나, C++ 클래스 내부에서 GameplayTag를 사용하고 있는 레퍼런스는 확인할 수 없습니다.
- 아마, C++ 내부에서는 FGameplayTag::RequestGameplayTag(FName)를 사용할 것으로 보이기에 태그 이름을 직접 전체찾기 하는 방법 밖엔 없을 것으로 보입니다.
- GameplayTag의 이름을 바꾸면, 원래 GameplayTag를 참조하는 Asset이 새 GameplayTag로 리디렉션 될 수 있도록 리디렉션이 생성됩니다.
- 이 부분을 꼭 숙지하고, GameplayTag를 변경할 때는 리디렉션을 정리하는 습관을 들이는 것이 좋습니다.
- 제일 좋은 것은 리디렉션을 생성하지 않도록 처음에 GameplayTag 규칙을 잘 정의하는 것입니다.
- 리디렉션 생성을 회피하는 방법으로 추천하는 것은 다음과 같습니다.
- 새로운 GameplayTag를 생성
- Search for References를 통해 기존 GameplayTag를 직접(manually) 새로 만든 GameplayTag로 변경
- 이전의 GameplayTag 제거
- GameplayTag가 Replicate되는 것은 GameplayEffect를 통해 추가되는 경우입니다.
- ASC는 Replicate되지 않도록 하는 LooseGameplayTags를 제공합니다.
- 이는 직접적인 관리가 필요합니다.
- 추가는 UAbilitySystemComponent::AddLooseGameplayTag()
- 삭제는 UAbilitySystemComponent::RemoveLooseGameplayTag()
- 만약 FGameplayTagCountContainer를 사용하고 있다면, TagMapCount도 직접 관리해줘야 합니다.
FGameplayTagContainer
- 다수의 GameplayTags는 FGameplayTagContainer를 통해 저장할 수 있습니다.
- TArray<FGameplayTag>를 통해서 저장할 수도 있으나, FGameplayTagContainer가 더 효율적입니다.
- Tag들은 기본적으로 FName을 사용하고 있으며, 프로젝트 설정에서 Fast Replication이 활성화 된 경우, 복제를 위해 FGameplayTagContainers에 효율적으로 압축됩니다.
- Fast Replication 옵션 활성화 되기 위해서는 Server와 Client가 같은 GameplayTag 목록을 가지고 있어야 합니다.
- GameplayTagContainers는 반복(Iteration)을 위해 TArray<FGameplayTag>를 리턴하는 함수도 가지고 있습니다.
FGameplayTagCountContainer
- FGameplayTagCountContainer에는 저장된 GameplayTag의 인스턴스 수를 저장하는 TagMap이 있습니다.
- FGameplayTagCountContainer에는 GameplayTag가 존재할 수 있지만, TagMapCount가 0일 수도 있습니다.
- HasTag() 또는 HasMatchingTag() 외 유사한 함수들은 TagMapCount를 확인해서 TagMapCount가 0이면 false를 리턴하도록 되어있습니다.
GameplayTagManager
- GameplayTag의 고급 기능을 원할 경우에는 GameplayTagManager를 살펴보면 좋습니다.
- 현재 GameplayTag의 parent나 child를 가져오고 싶은 경우에도 사용할 수 있습니다.
- 정의되어 있는 함수들은 GameplayTagManager.h를 살펴보면 어떤 것들을 제공하고 있는지 살펴 보면 다양한 기능을 할 수 있다는 것을 볼 수 있습니다.
- GameplayTagManager는 싱글턴으로 되어있기 때문에 사용하는 방법으로는
- #include “GameplayTagManager.h”
- UGameplayTagManager::Get().FunctionName()을 통해 접근할 수 있습니다.
- GameplayTagManager는 실제로 GameplayTags를 관계형 노드(부모, 자식 등)로 저장하여 상수 문자열 조작 및 비교보다 더 빠르게 처리합니다.
- GameplayTag와 GameplayTagContainers를 클래스의 멤버로 선언할 때 특정 태그만 보이게 할 수도 있습니다.
- UPROPERTY(Meta = (Categories=”GameplayCue”))로 선언하면 블루프린트에서 부모 태그에 GameplayCue를 가지고 있는 GameplayTag만 노출되게 할 수 있습니다.
- 특정 GameplayTag만 노출시키고, 사용할 수 있도록 하기에 좋은 옵션이니 꼭 기억해 두도록 합니다. (휴먼 에러 방지)
- 또는, FGameplayCueTag라는 별도의 구조체가 존재해서 GameplayCue의 상위 태그가 있는 태그만 표시하도록 할 수 있습니다.
- 비슷한 방식으로 함수의 파라미터도 특정 태그만 사용할 수 있도록 할 수 있습니다.
- UFUNCTION(Meta = (GameplayTagFilter = “GameplayCue”)) 를 사용하면 됩니다.
- 하지만, 함수의 GameplayTagContainer 파라미터는 필터링 할수 없습니다.
GameplayTag 변경에 따른 응답 신호 (Delegate)
- UAbilitySystemComponent(a.k.a ASC)는 GameplayTags가 추가/삭제 될 때마다 Delegate를 제공하여 사용자가 바로 알 수 있도록 하고 있습니다.
- 문법은 다음과 같습니다.
- AbilitySystemComponent→RegisterGamplayTagEvent(FGameplayTag::RequestGameplayTag(FName(”State.Debuff.Stun”)), EGameplayTagEventType::NewOrRemoved).AddUObject(this, &ASFPlayerState::FunctionName);
- EGameplayTagEventType 파라미터에 따라 이벤트를 받는 시점을 정할 수 있습니다.
- NewOrRemoved - 새롭게 추가/완전히 제거 된 경우
- AnyCountChange - TagMapCount가 변한 경우
- Callback을 받을 함수는 virtual 함수로 선언합니다.
- virutal void FunctionName(const FGameplayTag CallbackTag, int32 NewCount);
- CallbackTag → 콜백을 호출한 Tag
- NewCount → 새로운 TagCount
- virutal void FunctionName(const FGameplayTag CallbackTag, int32 NewCount);
- 주의, Delegate는 항상 등록 후 사용이 완료되면 해제해 줘야 합니다.
- UAbilitySystemComponent::UnregisterGameplayTagEvent(FDelegateHandle DelegateHandle, FGameplayTag tag, EGameplayTagEventType::Type EventType);
'UnrealEngine' 카테고리의 다른 글
UnrealEngine 5 Subsystem (0) | 2023.08.12 |
---|---|
GameAbilitySystem 기본 (0) | 2023.01.01 |
Actor 개념 정리 (0) | 2022.12.18 |