- Home /
Better to assign components to variables or reference directly each time
I am still trying to better understand how to optimize an Unity mobile app.
Is it better to do something like this - Example A - where the GetComponent is assigned at Start, rather than explicitly referred to, each time, as shown in Example B
Example A
var pTransform:transform; function Start(){ pTransform=GameObject.Find("player").transform; } function Update(){ pTransform.position+=Vector3(1,0,0); pTransform.localScale*=2; }
Example B
var player:GameObject; function Start(){ player = GameObject.Find("player"); } function Update(){ player.transform.position+=Vector3(1,0,0); player.transform.localScale*=2; }
Answer by Ashkan_gc · May 13, 2011 at 07:13 AM
it's always a better idea to cache everything. when you use GetComponent or properties like transform and rigidbody, unity have to go and walk in a tree and find the component for you. it's not much slow but can make a difference if it's called multiple times a frame and if it's on a mobile phone. GameObject.Find is really something that you should avoid in methods other than Start and Awake and any other method that is called once. don't call it in update or OnCollisionEnter or so unless you have to do so. always find all references at start or even create a list and tell every object required to add it'self to it. Dictionary can be useful too.
take a look at this video by the CTO from unite 07 for more info about caching.
if you want to, you can test it too. use both methods above with 1000 objects and take a look at fps or your profiler if you have pro to see how much more time the script takes to execute.
Answer by Dreamer · May 13, 2011 at 07:00 AM
This is a tricky question. I tell you what, why don't you do an experiment:
Example A
var pTransform:transform;
function Start(){
pTransform=GameObject.Find("player").transform;
}
function Update(){
**for(var i:int=0;i<100000;i++)**{
pTransform.position+=Vector3(1,0,0);
pTransform.localScale*=2;
}
}
Example B
var player:GameObject;
function Start(){
player = GameObject.Find("player");
}
function Update(){
**for(var i:int=0;i<100000;i++)**{
player.transform.position+=Vector3(1,0,0);
player.transform.localScale*=2;
}
}
Check the run-time fps to see which one is faster.
Answer by CHPedersen · May 13, 2011 at 06:49 AM
Yes, absolutely! Same with things like calls to GameObject.Find(). It's always better to cache references instead of looking them up each time. I'm not familiar with what Unity does behind the curtains, but it isn't unreasonable to expect that it stores GameObjects in some kind of master-list, then Components of GameObjects in a list for each GameObject. This means you'd have to traverse the lists for the target component every time you do a call to GetComponent or a search through all GameObjects with a comparison against a GameObject's name every time you do a call to GameObject.Find().
Edit: I just had a better look at your Examples A and B. In those cases, the optimization is probably non-existant since you're refering to the gameobject's transform, which doesn't require a call to GetComponent.
Edit2: Take a look at http://unity3d.com/support/documentation/ScriptReference/GameObject.Find.html where the documentation also recommends caching. :)
actually accessing transform component is no different. it's just a property that in it's get {} the code uses GetComponent.
Oh. O_O I didn't know that. Then I guess there is a bit of overhead to be saved from caching transform.