Search Unity

Feature Request Could we Consider a Robust Tag System?

Discussion in 'Editor & General Support' started by Jamoy1993, Oct 31, 2020.

  1. Jamoy1993

    Jamoy1993

    Joined:
    Jan 17, 2014
    Posts:
    14
    I have been thinking about this for quite some time now, the tag system as it is right now is not terribly good. Only allowing a single string to tag any game object. Before you go on and suggest adding a script to a game object to handle tags, this is unnecessary and is extra added steps upon what i have in mind, its not ideal to do many get components at run time as they are fairly expensive.

    What i propose is a list of key value pairs that you can define somewhere in the editor similarly to the way tags and layers are set. This will create a global enum for each tag type rather than a string so you can assign something meaningful that is tied to that "Tag". Like a price tag would be "Price" and the value would vary.

    The way i imagine such a feature being used is that you can select a game object you want and manually do it via the editor window or you can do it via code using a function call like this:

    Code (CSharp):
    1. gameObject.SetTag(GlobalTagType.Guid, "MyTotallyNotGuid");
    And to search the scene for an object with a certain tag, you can literally do a for-each through the scenes objects and find an object with a matching tag. Something along the lines of this:

    Code (CSharp):
    1. foreach(GameObject gameObject in scene)
    2. {
    3.       if(gameObject.TagsMatch(Tags.Guid, "MyTotallyNotGuid")
    4.       {
    5.          ///Do Stuff
    6.       }
    7. }
    Here are a couple of examples i could think of:

    Game Objects Team
    Game Object Instance ID
    Game Object Persistence

    That's all i could think of that i would use this for, it would probably be easier to think of such things if my use case was different.

    This will help me as i am creating a save system and at this moment i rely on changing the game objects name to its GUID for faster retrieval. I do this on load so performance is not a big issue but i would rather still have multiple ways to refer to this game object through native functionality. Now imagine doing this using a component for tags, Having to get the component for each game object just to compare tags? That would add a considerable impact to performance.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,727
    I don't know where these weird myths come from. Do you have a profiler run showing this is true?

    We already HAVE the .GetComponent() mechanism and I assure you it is extremely performant.

    Why is it performant? Because the entire internal architecture of Unity RELIES on GetComponent.

    To see what I mean, make your series of Monobehavior "tag" classes like this:

    Code (csharp):
    1. using UnityEngine; public class TagFoobar : MonoBehavior {}
    and

    Code (csharp):
    1. using UnityEngine; public class TagDingbat : MonoBehavior {}
    and you can sprinkle as many of those on the GameObject as you want, just go nuts.

    After you do this attach the profiler and you will see there is no measurable performance penalty, either CPU cycles or memory.

    When you hit something, check the tags you care about, act accordingly.

    Or do a FindObjectsOfType<> when it is time to generate a save file. It will be more performant than chasing down strings, I assure you.
     
  3. Jamoy1993

    Jamoy1993

    Joined:
    Jan 17, 2014
    Posts:
    14
    Getting a component once and caching it will always be faster than getting components every single time you need them. This goes for a multitude of different things and is one of my core principals of programming in unity. Simply not doing unnecessary function calls is a sure way to boost performance, if you can get away with only doing it once then why do it multiple times? I am not entirely sure of the internal code of the get component function. But i bet it searches an array of some sort attached to the game object / transform. Why search an array when you already have a reference to the game object and can implicitly access a tag array from there rather than wasting cycles on searching for a component attached to it?

    My specific use case covers potentially thousands of game objects. Imagine using get component on every single one of those objects to see if then has a tag class attached to it. It has to have a profound effect on performance. It is more cycles per game object, i have gathered this from a purely fundamental understanding of the way programming languages work.

    Secondly on the note of tidiness, would it not be nicer to just have the functionality built into the game object anyway?

    If there is an more efficient way to find a specific game object based on a unique identifier please let me know.
     
    Last edited: Nov 1, 2020
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,727
    I doubt there are any array searches going on. It's almost certainly a Dictionary type collection, hashed by the type.

    Your collection of string tags is gonna have to be searched the same exact way, so I don't see the performance difference.

    Your choice to pre-grab or runtime-grab stuff really has everything to do with frequency of access. If you only need it when you hit the save pedestal, just lazy get it. If you're banging on all the "bullets" (for example) every single frame, get them in advance or at the time they are created.
     
    noio likes this.