Is there a dictionary of tags stored somewhere? Does the engine iterate through every GameObject until it finds my tag? Is there a wiki page that explains how the engine deals with tags?
If you use CompareTag on a tag name that doesn’t exist, you get a run-time error. What I mean is, if you check for existing tag “enemy” when no enemies have been spawned, not a problem. But, checking for “emneny” throws a “no such tag” error. Clearly Unity is maintaining a list of all legal tags.
My guess is that object’s tags are actually stored in the objects as ints – the tag’s position in the list. FindObjectsWithTag("goat") probably looks up the tag# for goat and checks everyone against that int. Faster than doing string compares for them all. Even faster would be to make us use the tag numbers in the code (like we have to do for layers,) but no one can remember tag#5 is ground, and so on.
Storage for FindObjectWithTag is actually a database issue. If you think people will do it a lot, you can keep the list of all objects sorted by tag. The tagName list would have a pointer to the start of that tag. Or, each tagName could have a separate list pointing to items in the real list with that tag. Wastes a little time and space, but FindWithTag is instant.
The best solution is probably the obvious - searching through all game objects, and telling people that it is slow. Anyone who wants to speed it up can just keep their own list of enemies, and never has to use FindByTag.
Yep, it’d be awesome to know for sure. In my specific case the tagged object always exists and I can grab + keep a reference in the Awake method, but I’m staring at a stale pointer waiting to happen. However, I’m hesitant to look for tags in my Update loop until I know exactly how the tags work… I’d hate to parse my entire scene each frame.
Ideally they’d build a dictionary on startup with one list for each tag, GameObjects add and remove themselves to each list as they’re built and destroyed. Then FindObjectsWithTag(string) can forward an existing list.
Unity definitely stores int tags in the GameObjects. If your tag list has Element1 “Enemy” and you tag GameObject X “Enemy”… then you change your list to Element1 “Vehicle” and Element2 “Enemy”, GameObject X will now have the “Vehicle” tag.
That’s a good question - I was just thinking about this matter one of these days. The tags themselves are stored in the GameObjects, but I suspect that Unity has a parallel control structure (like a dictionary) to speed things up when searching for specific tags. Since tags are intended to identify groups of similar objects, one of the most commonly used routines is GameObject.FindGameObjectsWithTag(“tag”), which returns an array with all GameObjects with the specified tag - a function that is much more efficient if a dictionary is used.
I’ve not found any information about that, but I strongly believe that there’s an internal dictionary - which isn’t accessible to us, anyway.
EDITED: I have been using a more efficient trick: I create an empty object, reset its position and child to it all objects of some kind of interest. For enemies, for instance, I create an “Enemies” object and child every spawned enemy to it. This list is inexpensive, because Unity keeps it updated for us - we can use childCount to know how much objects exist, and iterate through the children when necessary. It’s better than calling FindGameObjectsWithTag each Update, since there’s no search or memory allocation.