2017년 2월 17일

Gameplay Tag를 활용한 언리얼 엔진 콘텐츠 분류 및 정리

저자: Ben Zeigler 테크니컬 리드

계층형 태그는 컨셉과 데이터를 정리할 수 있는 아주 유용한 방법이며, 게임플레이 태그(Gameplay Tags) 시스템은 언리얼 엔진 4에서 계층형 태그의 선언과 쿼리에 사용되는 수단입니다. 게임플레이 태그는 언리얼 엔진의 이전 버전들에도 이미 존재하던 기능이었지만, 언리얼 엔진 4.15에서는 인터페이스와 퍼포먼스 면에서 엄청난 발전이 이루어졌습니다. 따라서 지금이야말로 게임플레이 태그를 사용해 보기에 최적의 시기입니다. 하지만 게임플레이 태그는 무엇이고, 또 이것을 사용해야 할 이유는 무엇일까요?

게임플레이 태그는 “Family.Genus.Species.Subspecies”이나 “IndividualTag” 형식의 분류명입니다. 게임플레이 태그는 내부에서 FName 형식으로 구현되며, 검증을 위해 중앙 태그 사전(central dictionary)에 등록됩니다. 따옴표(‘, ’)를 활용해 이름을 중첩하여 정확한 태그를 찾기 위한 쿼리를 할 수도 있고, 부모 태그를 포함하여 태그를 찾는 쿼리도 가능합니다. 예를 들어 두 항목이 “Weapon.Ranged”와 “Weapon.Melee”로 태그가 되었다면, MatchesTag(“Weapon”)는 두 항목 모두에 true가 될 것입니다.  MatchesTagExact(“Weapon”)에서는 부모 태그를 무시하기 때문에, 두 항목 모두 false가 될 것입니다.

Gameplay Tag Containers는 수많은 태그들을 단번에 쿼리하기 위해 사용하는 Gameplay Tags 세트입니다. 태그는 구체적으로 추가가 되었을 경우에만 Exact 검사를 통과하지만, 일반 검사에서는 모든 부모 태그가 포함됩니다. Container.AddTag(“Weapon.Melee”)와 Container.AddTag(“Spell.Fireball”)를 호출했을 경우 Container.HasTagExact()는 “Weapon.Melee”와 ”Spell.Fireball”에서만 true가 될 것이고, Container.HasTag() 는 “Weapon”, “Weapon.Melee”, “Spell”와 “Spell.Fireball”에서만 true가 될 것입니다.

게임플레이 태그는 어떤 면에서 유용할까요? 먼저 게임플레이 태그는 디자이너가 입력할 수 있는 텍스트를 이름과 Enum의 조합처럼 유효한 이름의 집합으로만 제한을 하고 싶을 경우, 이름[a] 대신 사용하도록 할 수 있습니다. 이러한 계층 기능은 파라곤 같은 게임에서 중첩된 속성을 가지게 되는 피해 유형 등의 요소를 나타내기 위해 사용되었습니다. 예를 들어 일정 시간에 걸쳐 화염 피해를 입히는 능력들은 “Damage.DoT.Burn” 태그로 구분하였습니다. 그런 다음 “Damage”, “Damage.DoT”나 “Damage.DoT.Fire”를 탐색하는 블루프린트나 네이티브 코드를 등록할 수 있으며, 셋 모두 이런 특정한 경우에 발동하게 됩니다.

태그 등록

게임플레이 태그를 사용하려면 반드시 해당 태그가 중앙 태그 사전에 등록되어 있어야 합니다. 사전에 등록하는 방법 중에는 ini 파일을 활용하는 방법과 데이터 테이블을 활용하는 방법이 있습니다. 둘 중 어떤 방법으로 구성하든, 먼저 Project Settings UI의 GameplayTags 탭을 열어줍니다. 그러면 태그 관리 UI가 열리게 됩니다:

blogAssets%2F2017%2FFEBRUARY+2017%2FUsing+Gameplay+Tags+in+UE4%2FGameplayTags_Pic1-770x374-0e47d3e3442b8bb4aa1025c44fd524d212c9b5e4

ini 파일을 사용해 태그를 추가하려면, “Import Tags From Config” 옵션을 활성화 하십시오. 그러면 GameName/Config/DefaultGameplayTags.ini 파일 뿐만 아니라 GameName/Config/Tags에 있는 ini 파일에서도 태그를 불러오게 됩니다. 자신의 프로젝트에서 누구나 쉽게 태그를 추가할 수 있게 하려면 이 방법을 사용하는 것이 좋습니다. 이를 활성화 하였다면, 이제 태그 관리 UI나 태그 선택 인터페이스에서 Add New Tag 버튼을 사용할 수 있습니다. 현재 존재하고 있는 태그 옆의 + 아이콘을 누르거나, Add New Gameplay Tag 선택기를 여시면 됩니다:

blogAssets%2F2017%2FFEBRUARY+2017%2FUsing+Gameplay+Tags+in+UE4%2FGameplayTags_Pic2-770x386-e6e44771f619f6a59feb9316ddbffde622db9ab0

GameplayTagTableRow 유형의 DataTables을 활용하여 외부 태그 목록을 임포트하는 방식으로 태그를 추가할 수도 있습니다. 이 방법을 사용하려면 우선 DataTable을 임포트한 다음, Tags 설정 UI에 있는 GameplayTagTableList에 추가합니다. 또한 프로젝트가 시작되는 동안 AddNativeGameplayTag을 사용해 네이티브 코드로부터 직접 추가할 수도 있습니다.

태그가 사전에 추가되었다면, 이제 레퍼런스 검색이나 삭제, 혹은 태그의 이름을 바꾸는 등의 방식으로 태그를 관리할 수 있습니다. 관리 화면의 태그 옆에 있는 삼각형 드롭다운 메뉴 버튼을 눌러, 이러한 관리 기능에 접근할 수 있습니다. ini 파일을 통해 추가된 태그는 삭제만 할 수 있으며, 어떤 것으로든 레퍼런스가 불가능합니다. 이름이 변경된 태그는 GameplayTagRedirects 목록에 추가되며, 불러오는 중에 수정이 됩니다. 레퍼런스 검색은 레퍼런스 뷰어를 열어 해당 특정 태그를 사용하는 모든 애셋들을 보여줄 것입니다.

태그 활용

실제로 태그를 활용하려면 먼저 태깅을 시작해야 합니다. 첫번째 단계는 GameplayTag나 GameplayTagContainer 프로퍼티를 블루프린트나 네이티브 유형에 추가하는 것입니다. 만약 대상이 오직 한 가지 값만 가질 수 있다면, 단일 GameplayTag를 사용합니다(예를 들면 색깔은 동시에 한 가지 이상의 값을 가질 수가 없으니, UI Color 구조에 “Color.Blue” 태그를 추가할 수 있는 것입니다). 대상이 동시에 다양한 상태나 값을 가진다면, container를 사용합니다(예를 들면 NPC는 “Character.NPC”, “Character.Humanoid”, 그리고 “Gameplay.Important”의 태그를 지닐 수 있습니다). 일단 이런 프로퍼티를 추가하였다면, 블루프린트의 기본 뷰나 애셋 에디터에서 편집할 수도 있습니다:

blogAssets%2F2017%2FFEBRUARY+2017%2FUsing+Gameplay+Tags+in+UE4%2FGameplayTags_Pic3-770x574-2d2553661d89e278577f3590b5258fbb56b72957

이제 태그가 끝났으니, 이 태그들을 활용하여 쿼리를 하거나 게임플레이 코드로부터 필터링을 할 수 있습니다. 또한 C++에서 GameplayTagContainer.h로 정의된 작업들을 사용할 수도 있습니다. 가장 중요한 기능 중에는 개별 GameplayTag의  MatchesTag, MatchesAny, IsValid, 그리고 GetTagName 등이 있으며, GameplayTagContainer에는 HasTag, HasAny, HasAll, AddTag, 그리고 RemoveTag 등이 있습니다. Tag matching 함수는 부모 태그를 일치시킬 것이지만, Exact variants의 경우에는 특정 태그만 일치시킵니다.

블루프린트에서도 똑같은 작업에 접근하였겠지만, Exact 옵션은 알맞은 함수로 전달된 bool입니다. 다음은 Tag Container에 전달된 요소가 부모를 포함한 태그와 일치하는지, Make Literal Gameplay Tag 노드를 활용하여 확인해보는 기본적인 사례입니다:

blogAssets%2F2017%2FFEBRUARY+2017%2FUsing+Gameplay+Tags+in+UE4%2FGameplayTags_Pic5-770x250-67b202696a9c58bde2565cb6a12a90b96a6689a2

또한 GameplayTag 카테고리에는 “Switch on Gameplay Tag Container”와 “Compare Tag Container To Other Tag Containers” 등의 고급 노드도 이용할 수 있습니다. 4.15 버전 이전에도 이 중에 수많은 기능들을 이용할 수 있었지만, 보다 복잡한 구문과 UI를 사용해야 했습니다.

지금까지 게임플레이 태그를 여러분의 게임에 통합하는 방법에 대해 기본적인 개요를 살펴보았습니다. 에픽게임즈는 현재 게임플레이 태그를 다른 방식으로 엔진에 통합할 계획이지만, 현재 구비된 툴로도 탄탄한 성능을 발휘할 수 있을 것입니다. 에픽게임즈는 게임플레이 태그가 없었다면 파라곤을 비롯한 자사의 수많은 게임들을 발매하지 못했을 것입니다. 따라서 게임플레이 태그가 여러분의 게임에도 새로운 디자인 및 프로그래밍적 선택지를 제공해 줄 수 있기를 바랍니다.