Is there an alternative to GameObject.Find methods?

Hello, as always, great content!

I noticed that several classes make use of GameObject.FindWithTag method to get a reference of the Player, is there any less expensive method, pattern or any logic that would still enable the main Drop classes to communicate with the Player without needing to run such an expensive search?

I found several suggestions online, but all require some specific architecture to work properly, so I wanted to know if you had any recommendations.

Thanks in advance!

GameObject.FindWithTag is actually the least expensive method of finding the player, aside from creating a Player Singleton, which we have avoided in this course. It’s significantly (REALLY!) faster than FindObjectOfType<PlayerController>() because FindWithTag simply calls CompareTag(“Player”) on each object in the scene in order. FindObjectOfType has to go through each GameObject in the scene and examine each component until it finds a PlayerController component.

That being said, it’s still possible to utilize a Player Singleton while still not having that player persist between scenes (which complicates our saving system, and creates the potential for null references that have to be addressed). One’s first thought would be to have the PlayerController responsible for containing the Singleton, but I actually prefer to make a PlayerTag class

using UnityEngine;

namespace RPG.Core
{
    public class PlayerTag : MonoBehaviour
    {
         public PlayerTag instance;
    
         void Awake()
         {
               instance = this;
         }

         void OnDestroy()
         {
              if(instance==this) instance = null;
         }
    }
}

That’s it, that’s the whole class, and you slip it on the Player,
Then you can call

PlayerTag.instance

instead of

GameObject.FindWithTag("Player");
1 Like

Thanks for the reply, and for the detailed information about the cost of GameObject.FindWithTag.

Just to know, is there another approach to avoid using the Singleton-like solution?
Something that is not expensive but doesn’t end up using static instances?

I was thinking about events or some sort of message system, but that might be overcomplicating things for something that might have a simple, yet clean, solution.

Once again, you’re heading to statics… something like this would work, but it’s more complicated than a Singleton:

private static event Marco;
private static event<System.Action<ThisClassType>> Polo;

public static void FindInstance(System.Action<ThisClassType> callback);
{
    Polo+=callback;
    Marco?.Invoke();
}

void Awake()
{
    Marco+=InvokePolo();
    InvokePolo();
}

void InvokePolo()
{
     Polo?.Invoke(this);
     Polo = null;
}

So a class looking for the Instance would call ThisClassType.Marco with a method that takes in a ThisClassType variable and can then cache the instance and carry on with setup.

This is, however, quite cumbersome, and risks unintended bugs. At that point, a Singleton makes a LOT more sense.

I agree, there is no easy way to avoid the statics unless there is a change in architecture to ensure the dependency can be injected when needed.

So the best solution due to simplicity would be exposing the instance through a static, as you explained in the first answer.

Thanks again for taking the time to reply with so much detail.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms