Search Unity

Question CompageTag as a StringToHash? Is it possible w\o GetHashCode() or GetInstanceID() ?

Discussion in 'Scripting' started by KarlKarl2000, Jun 12, 2021.

  1. KarlKarl2000

    KarlKarl2000

    Joined:
    Jan 25, 2016
    Posts:
    606
    Hi @Eric5h5

    I've been curious about Unity's CompareTag and how to optimize it. I've got hundreds of OnTriggerEnter calls using this. CompareTag is a string, which from what I read on these forums, is a bad thing.

    I was researching and came upon InstanceID and GetHashCode(). But both of these don't seem reliable; based on tests I've done. Their values aren't permanent and I wasn't able to successfully get constant values at runtime.
    Code (CSharp):
    1.     private void OnTriggerEnter(Collider other)
    2.     {
    3.         if (other.GetHashCode() == 00000000) { } //this value changes every new game session
    4.         if (other.GetInstanceID() == 00000000) { } //this value changes every new game session
    5.     }
    GuID also seem to be an option, but it seems a bit inconsistent as well? Because objects can share the same GuID if it's from a prefab?

    So back to my question on CompareTag. Is there a way to get the CompareTag to look for an integer value? or can we convert the string to a hashcode? Similar to how Unity Animator.StringToHash? I looked around, but it seems no one is talking about it.

    I was thinking about using the game object's layer value, but it covers too many game objects.

    Code (CSharp):
    1. public class ExampleClass : MonoBehaviour
    2. {
    3.     void OnTriggerEnter(Collider other)
    4.     {
    5.         if (other.gameObject.CompareTag("Player")) //PLAYER <- How to make you an INTEGER??    =)
    6.         {
    7.             Destroy(other.gameObject);
    8.         }
    9.     }
    10. }
    Thanks for the help!
     
  2. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,992
    No, there's no way to test the tag with a hash of a string. However using CompareTag is not has bad as you may think. First of all when using CompareTag, the native C++ code is directly comparing the C# string which is passed literally as a pointer to the string. We don't know exactly how Unity implemented tags on the native side, however comparing two strings is not that bad. Of course it depends on the length of the strings and how fast they actually differ. So a string comparision will early exit at the first character that is different.

    However tags are not really meant to be unique identifiers. It's not really clear what you actually want to compare or use the tag for. You said you use it in OnTriggerEnter. So do you just use it to figure out the "category" / type of the object? If that's the case you can simply call GetComponent and attach scripts to your objects which you can identify. This has a bit of an overhead when testing in the editor when a component was not found. However in a build, GetComponent will actually return null if the component was not found.

    However without the exact usecase and concrete numbers it's almost impossible to give a clear suggestion. How many rigidbodies are we talking about? How often do those OnTriggerEnter get called?
     
  3. KarlKarl2000

    KarlKarl2000

    Joined:
    Jan 25, 2016
    Posts:
    606
    Hi @Bunny83

    Thanks for the clarification on CompareTag and string performance.

    For this particular case, OnTriggerEnter is used for triggering "combat" box colliders. Below is an example for combat, where two separate box colliders are using the tag "Fist" and tag "Sword". The enemy is able to distinguish the type of damage, based on the tag. But I have a lot like "LightFist", "mediumFist", "ShortSword", "HeavySword" etc

    Code (CSharp):
    1.     void OnTriggerEnter(Collider other)
    2.     {
    3.         if (other.gameObject.CompareTag("Fist"))
    4.         {
    5.             //Register Fist damage
    6.         }
    7.         if (other.gameObject.CompareTag("Sword"))
    8.         {
    9.             //Register Sword damage
    10.         }
    11.     }
    Btw is GetComponent performant? I read on the forum it's best to only call that at Start()? :confused:
    Thanks for the help! :rolleyes: