How do Gameplay Tags work?

I am trying to use GamePlay Tags but am running into an issue. Previously using the system before it was officially supported by the engine I could fire a ray at an actor and ask whether it has a certain gameplay tag to identify the actor without casting.

Now, however I have to cast to the class that has the tags and get the tag container and then ask whether it has the tag. Why has this changed? I’m not sure how to add Gameplay Tags to AActor in C++ so I can get any tags that any actor has without casting.

I have a feeling that I may be missing some important information about how the tag system works. It was a lot easier before and I don’t understand why it has been made more complex.

Hmm, could you really ask actors for gameplay tags before? I think what you could do was ask whether they have a FName as tag, and that functionality still exists.

I’ve heard in one of the streams that Epic wants to add gameplay tag support to actors, but that there are still some technical issues they are working on. Maybe somebody from Epic can confirm whether my recollection is correct, but my understanding was that eventually actors will implement something like IGameplayTagsAssetInterface so that you ought to be able to query them for gameplay tags without implementing your own subclasses or performing the “get a tags container from some component” dance. What you’re seeing right now are most likely the toothing problems associated with the introduction of a new feature into the engine.

But since I use gameplay tags fairly extensively, I can hopefully provide some information why they are pretty neat. Gameplay tags are rather similar to FNames in that they allow you to easily name things, however they are different in two important ways:

  1. They support hierarchical names.
  2. They provide a fixed but extensible set of names, which allows good support for tooling without limiting you to a set of choices determined in code, as enumerations do.

Let’s, as an example, say you have quests that take may take place in different regions of your map, but some quests are not bound to any particular region. Then you can easily define a set of gameplay tags Region.Default, Region.Awsometown, Region.Awsometown.BarberShop, Region.Horriblecity etc. When your designers then design quests, they can chose the quest regions from a drop-down menu, so they don’t have to remember what the individual places were called, and they can easily add new tags while they are defining quests, etc. Here’s how it looks without any further work on the programmer’s part:

In your program you can easily special case some gameplay tags, such as Region.Default and it’s much less likely that designers enter Region.None instead of Region.Default when they want to define a quest without associated region.

Granted, gameplay tags offer very little that you could not have achieved with FNames, some definitions, and some property pane specializations. But they are the proverbial 80% solution for many problems that you can now solve without any custom code.

Regarding casting and getting the tag container from somewhere: Right now, if you are using gameplay tags it’s probably best to define your own actor subclasses that implement IGameplayTagAssetInterface. In that way you can query everything that supports tags with HasMatchingGameplayTag (or the any/all tags variants), and you don’t have to remember where the tag container comes from. You do have to cast once, though.

In another project where I implemented gameplay tags I could do this and it would work.

This does not work in my other project.

That’s interesting, I didn’t know that this worked in the past. But on the positive side, this makes it more likely that better support for gameplay tags will land in one of the next engine versions.