Reference manager class Performance? gameobject.find instance var vs class var

Hi,

I have prefabs that some reference the same 15 objects and use the gameobject.find within a script on those objects to establish a reference in the scene when they are instantiated to other gameobjects. I read online of people using a static class with references so instead of using the slow gameobject.find I can just do something like this:
public class RefManager : MonoBehaviour
{
static RefManager instance;
void Awake() { instance = this; }

public GameObject MyRef1;

//use this in prefab script
public static GameObject MyRef1 { get { return instance.MyRef1; } }
}

//in prefab
var inPrefabVariable = RefManager.MyRef1;

Is this a good idea for performance vs gameobject.find to establish 15 references all at once on instantiation?

Definitely. GameObject.Find is arguably one of the least efficient ways to reference something and should only be used as a last resort.

Getting a reference from a manager instead means you don’t have to search every single GameObject in the scene for the specific one you’re looking for. It’s reference already exists.

For initialization code like this though, it doesn’t matter too much, but in cases where it may need to happen after initialization, then yes, use the manager method.

1 Like

Thanks, here is another question. If I have 15 prefab objects in my scene that each hold 12 references to child objects on themselves, is it better to call gameobject.find(“childObjectOfThisGameObject”) inside the methods on the prefabs when needed or have class variable references on the prefabs already set resulting in 180 references in memory when all 15 objects are in my scene. Kinda been wondering this for a while when does gameObject.find within a method for a instance variable make more sense then lots of class variable references on the object.

I appreciate any feed back as I cannot seem to find any threads online about that question.

That really depends on if you need these objects to be constantly or occasionally referenced.
If constant, go with having already-defined references. If occasional, getting a new reference to them is fine.
There may be other factors in play here such as how “big” each GameObject reference is. You won’t find out for certain which method would be better until you try them out.

With software development in general, one of the golden rules is to first make it work, then make it efficient.

Also, GameObject.Find() cannot be used in the way you’re describing here. It can only search the entire scene for a reference by name. You can use Transform.Find() however, which does only search a GameObject’s children for a reference by name.
There is also Transform.GetChild() which takes in an index parameter and returns the child GameObject at that index in the hierarchy. Transform.GetChild() is faster than Transform.Find(), however you do need to know the index of the child object, and adding/removing other child objects can break it, as the index may change.

4 Likes

As Vryken suggests, err on the side of keeping references vs searching, and if you have to search, keep what you found.

In general, a prefab should not use any search functions to find things you know are already inside the prefab. A prefab may search the scene for necessary external items on startup, or wherever possible, the top object in a prefab should have public references that the level designer or instantiating script can fill in when they use the prefab.

2 Likes

Unity Technologies wrote some tips regarding GameObject.Find etc, see “Avoiding expensive calls to the Unity API”:

2 Likes