- Home /
Is there a more efficient way to write a "Find" script?
I'm working on Android Unity Pro. My game has hundreds of "Find" scripts and I trying to optimize performance. Is there a better way to avoid writing a "Find" script? Below is a typical "Find' script in my game. If someone could teach me how to write it more efficiently I'd appreciate it. thanx
function OnTriggerEnter( myTrigger : Collider){
if(myTrigger.gameObject.name == "tum1-2"){
var myTryagain : CameraControls = gameObject.Find("Main Camera").GetComponent(CameraControls);
myTryagain.enabled = false;
}
}
Answer by syclamoth · Jan 09, 2012 at 11:42 AM
You really shouldn't have to use GameObject.Find ever, under any circumstances. If you ever find yourself using it, have a good hard look at what you're doing and make sure there's not a better way.
For this specific example, is there any reason why you can't just keep a reference to that 'CameraControls' object in your component, instead of finding it every time you enter a trigger?
A 'reference' is a variable through which another object can be accessed. It's a pretty common program$$anonymous$$g term.
If the script is on a different game object, just have a variable
var myTryagain : CameraControls;
and set it up in the inspector, at the very least. Then you don't have to use gameObject.Find.
Or, you can keep a reference to the 'main camera' object, and use that.
Either way, you never have to use GameObject.Find. I cannot thing of a single situation in which it is the correct thing to do.
I upvoted this reply out of pure spite - The ratio of experts to newbies at Unity Answers is about as ridiculous as the US budget deficit, so downvoting one and then creating a new question with one of the experts' name in it just to attract attention is not the way to go. :-(
On a technical note, I don't agree entirely, though. ;-) I do feel there are situations where GameObject.Find is acceptable, such as caching references to gameobjects on startup. I realize you can use the inspector to set up variables, but I think this approach obfuscates the assignments that take place at runtime. Code should be self-explanatory on its own - you should be able to glean from the source itself where the value of each variable comes from. Declaring a variable like so: "var something : float", and then setting its value in the inspector makes the variable appear uninitialized in the source file.
In addition to this, don't variables have to be public before you can edit them in the inspector? From an OO point of view, forcing public access is an antipattern.
Answer by Jodon · Jan 09, 2012 at 02:45 PM
Having a public reference to your Camera certainly solves this issue as syclamoth has stated. However, you're actually looking for the CameraControls component, so having a public variable in your class that points to the component is more efficient in this case.
Another approach would be to write an Awake() or Start() function and use gameObject.Find in there, save the results to a class variable (preferably a private variable), and reuse that variable in the OnTrigger. This will ensure your Find() performance hit occurs only once, not every frame you're in the trigger.
A third way would be to use Camera.main which is a static variable that always points to the "main" camera. http://unity3d.com/support/documentation/ScriptReference/Camera-main.html. Depending on Unity's implementation, this could also be a bit slower than the techniques mentioned above. You could however combine it with suggestion #2 (the Awake()/Start() caching).
Finally, you should probably avoid the .name == "tum1-2" string comparison as string compares can be slow. You could use the same suggestion of using a public variable to store the object "tum1-2" that you're looking for. I would think this particular code actually belongs in another class though, one where you know you're dealing with tum1-2 directly (e.g. should be in a behaviour that attaches to tum1-2) then you can avoid the whole name comparison/object comparison issue all together.
Sorry I didn't write any code for you but I don't write in JavaScript and would not want to provide you with non-working code.
Your answer
Follow this Question
Related Questions
Is there a more efficient way to writ a "Find" script? 0 Answers
Finding inactive game objects in a pool 1 Answer
How does gameobject.find() loop through the hierarchy? 3 Answers
On Android. How many lights can you have in a Scene or the total game? 1 Answer
[Android] Significantly Worse performance on better device - 64bit CPU problematic? 0 Answers