GameObject.Find(...)

I have noted many people saying that this function is inefficient and to minimize calls to it…yada yada yada.

So is their likely to be any significant gain, re efficiency, to build a binary tree of game objects at start up and implement a custom Find(…) function that traverses such a tree?

Or would folks regard the gains to be not worth the effort?

If in doubt profile.

But it really depends on why you need to keep using Find

this was wrong

3 Likes

no

1 Like

I am actually using GameObject.Find(…) in void Update(), but in response to user input rather than just running constantly. And I am using it only when I can’t do transform.parent.gameObject.SendMessage(…) due to my gameobject hierarchy .

So it sounds as though, in this scenario, I am fine using it in Update().

Actually, I came up with a MFC message map like system for communicating between modules with unique int message IDs.

I started of doing the standard SendMessage(“FuncName”, object") thing but I quickly recognized that this was going to degenerate into spaghetti code.

I am still using SendMessage(“FuncName”, object")but my base class is routing the messages through a single overridable function that all script have by inheriting my base class.

protected override void DoReceiveMessage(Parameters p)
{
base.DoReceiveMessage(p);
if (p.m_nMsgID == MessageIDEnum.MSGID_BUTTON_CLICK)
{
string strSendName = (string)p.m_objParam1)
.
.
.
}
else if (…)
{
}
}

So at least you only have to look for one single function in all scripts to get an idea of its major functionality.

The greater problem with relying on Find is the fact you have to ensure everything has a unique name. I’ve yet to figure out where I need find beyond simple setup for artist convenience - ie I’ve never actually found a use for it in gameplay (nor would I consider it reliable).

2 Likes

I am using Find(…) and SendMessage(…) as a generic means to invoke functions in scripts without having to instantiate my specific script.

As in MyScript s = GetComponent();

This method of invoking functions in your scripts completely breaks the whole inheritance/polymorphism paradigm of object oriented programming. There is no way you can push common functions back into a generic base class that can be re-used in different apps.

If it was implemented in Unity something like the following then it would be fine.

Script s = GetComponent();

Since the editor already stores the name of a cs file if you add one to a game object, it shouldn’t be all that difficult figuring out what functions and classes are available in the generic Script object.

Surely it is not that difficult if the name you give a game object reflects its purpose or function plus numbering if more than one is needed.

1 Like

But why when you can drag in your reference or get it via a other means. More can go wrong when trying find objects via string. Just seems your fighting the system when their are better solutions to this problem.

1 Like

He is right. As a rule string based programming is evil. You are giving up all of the comforts of a modern compiler and racing out on your own. Both Find and SendMessage are prone to this problem.

1 Like

I did start doing that at first. But even with a Bingo Game with 75 balls, dragging and dropping that number of objects is a bloody pain in the ar$e.

And then if you happen to want to change the name of your script for what ever reason…

Bugger that - I would rather use Find(…) and do away with the drag and drop links.

And again NOT having drag and drop game object links is more amendable to inheritance and polymorphism.

Uniquely naming them for find to work is also a pain. :wink:

A couple of approaches of used to do the same thing.

  • Instantiate the objects at runtime. Keep the references.
  • Set up the objects as children of a single parent. Grab the references by iterating through children.
  • Have the objects register themselves with a manager in Start.

Your way works too. Just putting out some options to consider.

2 Likes

I don’t really agree! What is so evil about string based programming? The Unity editor is full of strings after all!

Besides, the WHOLE point of object oriented programming is the create RE_USEABLE code elements through inheritance and polymorphism.

At least that is what Latrobe University (Victoria, Australia) taught me.

To my way of thinking the general Unity way of coding is going against the intent of object oriented programming in general. So I am merely finding ways to adapt Unity to take as advantage of C# inheritance etc as far as is possible.

I see little point in re-writing the exact same code in 100s of different scripts and having to alter 100s of separate script if I want to make an identical change in all of them. Better by far to have them all inherit a base class and make the code change in ONE script.

An example in my Bingo3D app…

BaseButton -->BasePush Button
|
→ BaseToggle Button

Both the latter have three possible states: ‘pushed’, ‘not pushed’ and ‘disabled’.

This is accomplished by supplying the derived button classes with three sprites corresponding to the three states.
The basic functions of enabling/disabling, pressing and unpressing etc is done in BaseButton - it is identical for both button types.

BasePushButton and sets a pressed state briefly and then return to an unpressed state in response to user input. BaseToggleButton sets the opposite state and retains it upon user input. Then actual scripts I attach directly to game objects do not much more than supply the specific sprites. This is what object oriented programming is supposed to be all about.

I cannot see any advantage to having two separate PushButton and ToggleButton scripts, that I attach to actual game objects, and that contain identical segments of code. That is not proper object oriented programming based on what I was formally taught.

1 Like

I think you need to look at your approach, since I can assure you their are much better ways than having to search for or assign that many references

Horses for course I suppose - I don’t have any problem with naming objects and scripts uniquely…at least not so far.

I find it FAR more irritating (and slow) having to repeat identical code segments in multiple scripts.

1 Like

Not repeating code in scripts seems like a good solution. you can reuse components and components can use inheritance and interfaces.

Look in all the years I have been programming in a respectable variety of different platforms, I have not come across a better naming convention (for classes, data members, functions,…) than the one generally used in Microsoft Foundation Classes for Visual C++.

So I try to broadly stick to that sort of naming convention in my Unity scripts, game objects, sprites, Arduino sketches, PHP and javascript,…

And I rarely run into the problem of running out of unique names.

1 Like

Why does people keep assuming this?

I’ve seen the same said about FindObjectsWithTag too. Both of the operations are linear. They do a search of all your objects. They’re O(n) operations where n=number of objects in the scene.

If you actually check (Like I just did, again, just to be safe), increasing the number of objects in the scene increases the amount of time it takes for GameObject.Find to run. It’s still fast (0.03 seconds with 200k objects on my computer), but it’s not constant time. Note that the earlier the object is in the hierarchy, the faster it’s found (so ~0 seconds with 200k objects if the object is the first), so the implementation is probably dead simple.

Both the misconception about FindWithTag and Find must build on some idea that Unity has a cache of names it maintains behind the scenes and uses for the lookups. There’s no such thing.

EDIT: And to the discussion that sprang up: don’t base your code around there being specific strings in the scene. That breaks all and any chance of reusability, and misspellings can and will be your doom.

2 Likes

I have fiddled around with these a little but I am not clear how they address identical code segments that are repeated in multiple scripts. I don’t see how interfaces can address identical code segments in my button classes outlined above for example.