Download

Registering UEnum as GameplayTags Automatically (C++)

Hey guys, following the recent blog post from here: https://www.unrealengine.com/blog/using-gameplay-tags-to-label-and-organize-your-content-in-ue4#comments-top
which explains how to use the ‘newly official’ GameplayTags system, I’m posting here a little trick to help you convert any UENUM to GameplayTags automatically without having to create extra DataTables or managing INI files.

Ok so, to do this, you’ll need a little list of things:

  • Someone familiar with C++ and modules.
  • Know the native name of the Enum you want to convert.
  • The ‘friendly’ name of the Enum must follow GameplayTags convention, using the “.” character when needed in its Display Name.

Practical example, let’s say you have anywhere in your game code UEnum declared like this;
Note what I did with its meta data, ‘DisplayName’… That is how the Enum will be named in Unreal’s Editor UI:



UENUM(Category = Toolset, BlueprintType, meta = (**DisplayName** = "Classes.Character.Species"))
enum class **ECharacterSpecies** : uint8 {
	Unknown,
	Human,
	Animal,
	Beast,
	Dwarf,
	Elf,
	Giant,
	Zombie
};


We are going to use the DisplayName meta data as one of the base GameplayTags categories;
To do so, I have created in game module a new header file with a new class, like this:

[MyGameTags.h]:




#pragma once

#include "**GameplayTagsModule**.h"

/// This is just for readability, reducing code cluttering.
#define MANAGER UGameplayTagsManager::Get()



class MODULENAME_API FGameTags {
 public:
	static FName IEnum(UPackage* Package, FName Name);
	static FName IField(UPackage* Package, FName Enum, int32 Field);
	static void RegisterEnumAsGameplayTags(UPackage* Package, FName Name);
	static void RegisterGameplayTags();
};


And then setup the class functions in the cpp file;
[MyGameTags.cpp]:




#include "MyGameTags.h"


FName FGameTags::IEnum(UPackage* Package, FName Name) {

	const auto &Object = FindObject<UEnum>(Package,*Name.ToString(),true);

	if (Object) {
		return *(Object->GetDisplayNameText().ToString());
	} return TEXT("");

}


FName FGameTags::IField(UPackage* Package, FName Enum, int32 Field) {

	const auto &Object = FindObject<UEnum>(Package,*Enum.ToString(),true);

	if (Object) {
		FString EN = Object->GetDisplayNameText().ToString();
		FString EF = Object->GetEnumName(Field);
		FString Parse = EN+FString(TEXT("."))+EF;
		return FName(*Parse);
	} return TEXT("");

}


void FGameTags::RegisterEnumAsGameplayTags(UPackage* Package, FName Name) {

	const auto &EN = FindObject<UEnum>(Package,*Name.ToString(),true);

	if (EN) {
		MANAGER.AddNativeGameplayTag(IEnum(Package,*Name.ToString()));
		for (int32 E=0; E<EN->NumEnums()-1; E++) {
			MANAGER.AddNativeGameplayTag(IField(Package,*Name.ToString(),E));
		}
	}

}



void FGameTags::RegisterGameplayTags() {

	RegisterEnumAsGameplayTags(ANY_PACKAGE,TEXT("ECharacterSpecies"));

}


#undef MANAGER


Note this line, all we have to do now is tell the function the name of the UEnum I want to convert to GameplayTag;
This string passed is exactly the name of the native UEnum declared up there:



RegisterEnumAsGameplayTags(ANY_PACKAGE,TEXT("***ECharacterSpecies***"));


Now, to automate things, we need a simple Editor module for the game, set to load at “PostEngineInit” phase:



#pragma once

#include "MyGameTags.h"
#include "ModuleManager.h"


class IMyGameEditor : public IModuleInterface {

 public:

	static inline IMyGameEditor &Get() {
		return FModuleManager::LoadModuleChecked<IMyGameEditor>("MyGameEditor");
	}

	static inline bool IsAvailable() {
		return FModuleManager::Get().IsModuleLoaded("MyGameEditor");
	}
	
};


#define LOCTEXT_NAMESPACE "Namespace"


class FMyGameEditor : public IMyGameEditor {

 public:
	void FMyGameEditor::StartupModule() {

		**FGameTags::RegisterGameplayTags();**
		
	}
	
};

#undef LOCTEXT_NAMESPACE


Whenever changes are made to that Enum, after compiling when the Editor is open again, your team will have GameplayTags automatically changed to match whatever items you have in your Enum now;
Result for the UEnum above generated tags like such:

I bet this is going to be useful for a lot of teams out there so, sharing :wink:
Good luck!