Overview
Useful as a more flexible enum type.
Implement IGameplayTagAssetInterface to support more of the builtin gameplay tag operations. Gameplay Tags can be used without implementing the interface if necessary, but then you won’t be able to use many of the builtins which take advantage of it, and instead have to work directly on a gameplay tag or gameplay tag container - usually via casting or a custom interface.
Why use GameplayTags? What for?
GameplayTags are useful any time you need to identify something. For example, you can use them to identify something uniquely, or as a member of some grouping, etc. - how you want to use it is entirely up to you.
Here’s a few ideas:
- Identify NPC’s by type and grouping - Tags such as
Npc.Hostile.PistolGuy
orNpc.Friendly.Peter
can be used to identify an NPC by its grouping (hostile or friendly), its type (PistolGuy) or a unique NPC called Peter. For example, grouping by hostile/friendly could be used as part of AI perception, and identifying by type or unique name could be used for identifying them for other kinds of gameplay logic. - Identify damage types -
DamageType.Fire
,DamageType.Fall
, etc. - you can also use more specific tags likeDamageType.Fire.Fireball
, which allows you to again identify by grouping (for example for damage resistance or such), and by specific type for logic (f.ex. if you wanted to display a message “cool fireball” when an NPC sees you use one) - Identify different areas of your level -
MyLevel.House
,MyLevel.Swamp
, etc.
In other words, any time you would use an ID or other categorization, consider using gameplay tags. Enums are another common choice, but gameplay tags can be more flexible. When using enums with different groupings, you often have several enums types - this can be troublesome when you need to use all of your enums for logic, as they are unique types. Gameplay Tags can be a better choice, as you can treat all the tags as Gameplay Tags and compare their hierarchy instead.
Usage examples
Adding native gameplay tags
As of 4.27 you can add native tags using a set of macros - this is the preferred way to define tags in C++.
//put into a .h file
UE_DECLARE_GAMEPLAY_TAG_EXTERN(MyGameplayTag)
//put one of these into a .cpp file as a pair for above
UE_DEFINE_GAMEPLAY_TAG(MyGameplayTag, "My.Gameplay.Tag")
UE_DEFINE_GAMEPLAY_TAG_COMMENT(MyGameplayTag, "My.Gameplay.Tag", "Comment explaining tag usage or otherwise")
//put this into a .cpp file alone if the tag is only used within that cpp file and nowhere else
UE_DEFINE_GAMEPLAY_TAG_STATIC(MyGameplayTag, "My.Gameplay.Tag")
The usage style is similar to macros for Logging:
DECLARE..EXTERN
is used in the header file, withDEFINE..TAG
added in the cpp file. This allows using the tag from other files by including the header.DEFINE..STATIC
is used within a cpp file, and only allows using the tag within that specific file- The parameter
TagName
is the C++ identifier that will be created for the tag, such asTAG_MyTag_For_SomePurpose
- The parameter
Tag
is the actual tag name, such asMyTag.For.SomePurpose
_COMMENT
can be used to give the tag a description which can be seen in editor
Idioms for usage in C++ pre native tags
There is no reason to use these methods as of UE 4.27 - use the macros listed above instead.
Since gameplay tags are easily declared in editor (and saved into the config files), it’s easy to use them from the UI. There’s no “typesafe” obvious method for doing it in C++, but the following are options for it.
Using via #define
//Let's assume we have a tag called MyActor.SkillName
//so we define a constant for it like so
#define TAG_MYACTOR_SKILLNAME "MyActor.SkillName"
//We can then use it easily in our C++ code
FGameplayTag SomeTag = FGameplayTag::RequestTag(TAG_MYACTOR_SKILLNAME);
You can alternatively define the RequestTag
function call as part of the constant.
This definition can be put into its own header file, along with definitions of your other tags.
Using via an engine subsystem
In engine subsystems, you can subscribe to OnLastChanceToRegisterNativeTags
, and register your gameplay tags from there. This way you don’t need to save them into the configuration which can be useful if you have a lot of tags.
Tags as function parameters
You can specify a specific parent tag as requirement for functions parameters:
UFUNCTION(BlueprintCallable)
void Whatever(UPARAM(meta=(Categories="Some.Parent.Tag")) FGameplayTag Param);
This limits tag choice to the ones under the given parent.
Common issues
Other
- An interesting plugin which allows creating “filtered gameplay tags” https://github.com/MaksymKapelianovych/FilteredGameplayTags