Hey all! I’m trying to wrap my head around tags in Unreal, and for the life of me I can’t find a single resource online that actually explains this.
What I want to use tags for is very simply to be able to set an appropriate tag or tags on Class A, and then from Class B, be able to check (say on a linetrace, for example) whether Class A has a specific tag.*
As I understand it, there’s the older system of actor and component tags, and the newer system of gameplay tags. Actor tags would seem to allow me to do this very easily. Set an actor tag in Class A, check for it from Class B. No casting, interfaces, or anything else required. However, every resource I’ve found online suggests that actor tags have been deprecated in favor of gameplay tags. The problem is that nowhere actually bothers explain how to check if Class A has a specific gameplay tag from Class B. Every tutorial and guide I’ve found - both in Blueprint and C++ - only goes over how to check in Class B if a gameplay tag container also within Class B has a specific tag. Utterly useless for my purposes. I’m sure there’s some method to achieve this, but I don’t want to fuss around with having to writing whole new interfaces or casting to the thing I hit when the entire point of using tags is explicitly to avoid doing those things. At this point I’m questioning whether gameplay tags even are a replacement for actor tags, or whether these two systems are intended for different things.
If anyone could take the time to explain this to me like I’m five (preferably with applicable C++ examples), I’d be extremely grateful.
*(Specifically, I’ve got a number of different types of actors in the game world that can all be interacted with by the player via an interface. Some actors can be grabbed and carried around the world as physics objects, others are pieces of equipment that can picked up an placed in an inventory, others are just things like buttons and doors that fire one-off events when interacted with. I’d like to be able to assign tags to these as appropriate so that the player class knows when to, for example, take ownership of the other actor (for replication reasons), or do anything else that can’t be easily called on the other actor’s class through the interface).
EDIT 1: I’ve found something about a built in interface called IGameplayTagAssetInterface. If I’m understanding correctly, I can tell any class I want to use tags to implement this interface, then add the appropriate tags to a class using the
MyGameplayTag = FGameplayTag::RequestGameplayTag("Family.Genus.Species");
syntax, then use something like (not 100% sure on the syntax, will experiment)
if (ClassA->HasMatchingGameplayTag(FGameplayTagMyGameplayTag )) { MyFunction(); }
Going to try this, will report back!
EDIT 2: Yeah didn’t work, which I should have realized because the engine wouldn’t just know that ClassA even implemented that interface unless I did something like cast to it or used an “if implements interface” check.
I suppose I might be able to write a function in the existing interact interface to check for tags, but then I’d be stuck doing the same for anything else I want to use tags for. I’ll keep the thread open in case anyone knowledgeable enough is feeling generous enough to walk me through it, but for now I’m leaning toward keeping things simple and just using the actor tag method.
EDIT 3: Well I gave up on gameplay tags (at least for the time being) and decided to just use actor tags instead. No hierarchical features or editor support, but they’re dead-■■■ simple and work for what I want. If anyone stumbles across this thread in the future and wants to know how to use them (because even this was amazingly poorly documented), the syntax couldn’t be simpler:
Just pop this in the constructor of the actor you want to tag:
Tags.Add(FName("YourActorTag"));
And call this from an appropriate function in the actor you want to check for that tag from:
if (TaggedActor->ActorHasTag("YourActorTag"))
{
*Do something *
}
There are almost certainly better ways of doing this if you’re dealing with larger numbers of conditions, but for simple checks it should work fine