UnrealEngine

GameplayTag

Ms_Tony 2023. 2. 6. 23:59

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
    • 주의, Delegate는 항상 등록 후 사용이 완료되면 해제해 줘야 합니다.
      • UAbilitySystemComponent::UnregisterGameplayTagEvent(FDelegateHandle DelegateHandle, FGameplayTag tag, EGameplayTagEventType::Type EventType);

 

참고 문서 : https://github.com/tranek/GASDocumentation

'UnrealEngine' 카테고리의 다른 글

UnrealEngine 5 Subsystem  (0) 2023.08.12
GameAbilitySystem 기본  (0) 2023.01.01
Actor 개념 정리  (0) 2022.12.18