- Home /
Alternative to getComponent?
Ive been reading around, and it sounds like getComponent() is fairly slow. In my game (which I would like to port to mobile in the future) I use it fairly often just to check/change a single variable in a script attached to an object. Is there a more efficient way of accomplishing this to increase performance or is this the only option?
Thanks, Any ideas are appreciated.
I think we would need to see some code. Usually you can assign the result of GetComponent to a variable and therefore only use it in Start. However, it depends what you're doing.
I have a bunch of code running on mobile (iPad3) which is littered with GetComponent, and it runs fine. It gets used for 3DText, scripts (of course) and grabbing specific colliders.
I have a few places where I've cutNpasted 5-6 identical getComponents in a row, just prototyping an explosion or something. Figure I'll clean up the code if we want to keep it. Half the time, the code gets deleted and I'm glad I didn't waste time speeding it up. The other 49% of the time, it looks good, runs fast enough, and I just leave the code alone, GCs and all.
I personally like getComponent bc I can call a method or even a variable from a single line without storing a variable for it like for example.
Foreach (Transform waypoints in waypointNodes) {
waypoints.GetComponent().StartLooking(this); }
Answer by Owen-Reynolds · Apr 02, 2014 at 03:05 PM
Lookup "unity getComponent cache."
Whenever you compute something you're going to use a few times, you can save it in a variable. Nothing fancy at all. Instead of if(A.magnitude<10 && A.magnitude>3 ...
you write float Amag=A.magnitude; if(aMag<10 && Amag>3)
. If you have to think harder about how and where to save it, the fancy term is "cache-ing" it, like canned goods in a safehouse.
The trick with getCompnenent is, you can declare variables of type Rigidbody, or script names, Renderer... . Then you have a place to save a GetComponent.
But, if you only use it once a every few seconds, maybe not worth the effort and harder to read code.
Answer by Eric5h5 · Apr 02, 2014 at 03:47 PM
GetComponent is really not particularly slow. You should profile/benchmark first to be sure it's actually a problem rather than relying on misinformation.
It's a slow operation in computation terms. Using it once or twice won't cause a problem, but using it repeatedly will cause your program to slow down if you do it enough times.
No, not really, unless you define "enough times" as "hundreds or thousands of times per frame", which is not something you'd normally be doing anyway. Like I said, profile or benchmark.
It does not take thousands of GetComponent calls per frame to cause noticeable lag. It is variable on a number of things, not just the number of calls, but from my experience it's well under 100 per frame before it starts beco$$anonymous$$g noticeable, if not detrimental. Even so, it's still a slow operation even if not noticeable, so best to avoid doing it too much. Computational costs add up.
even if the speed up is not noticeable
Yeah, that doesn't logically follow. Caching the component isn't free; it requires memory and developer time. Not much of either, but if the result as you say is not noticeable, then the "optimization" was a waste, plus you're adding complexity and global variables, which slightly increases the chances of bugs. Use the profiler, and if it would actually make a difference, then replace GetComponent calls with cached calls when you're otherwise done with the game. It's clearly not the case that it's "always" worth doing.
The wikipedia page for Program Optimization addresses all the major points really well.
But Hoeloe clearly has religion on this one. Clai$$anonymous$$g O(n) for a search on the component list, almost always 4 or fewer items, and never more than 10? (the first concept we $$anonymous$$ch about big-O is it only makes sense for large, semi-unbounded values of n.)
But, the thing is, there's cargo-cult nonsense all over, and nothing we can do about it. The OP was "reading around" how GetComponent is slow. Because dozens of answers to "how to read a var in another script" swerve into how you should cache everything, including your own Transform (but think nothing of using gameObject.transform.rigidbody
.)
As wrong as I think Hoeleo is, the new plague of Unity UTube tutorials is worse (how is watching a guy stutter while panning through the code, better that a documented sample project?)
Answer by perchik · Apr 02, 2014 at 03:08 PM
There's a few options.
1) As @hamster said, it's typically not a terrible thing to do a GetComponent on Start and save it to a variable. Usually performance hits at startup are okay because people expect that games have to load:
private SomeScript foo;
void Start()
{
foo = GetComponent<SomeScript>();
}
2) If you make a public variable you can drag the gameobject with that component to it in the editor:
public SomeScript foo;
void Start()
{
if(!foo)
Debug.LogError("No SomeScript component");
}
And then you can drag a gameobject with a SomeScript component on it to the foo slot in the editor
I've been using the second approach and it works fine in most cases. It's nice to see in the editor the dependencies your objects have. If you plan on adding/removing objects a lot it might be a bit more work to maintain though.
Also, sharing between multiple computers, sometimes we've had issues where the editor links get lost. That is, we know there's supposed to be a gameobject assigned to it, but it fell off somehow. In smaller projects its easy to track down, in large ones, we've found using getcomponent avoids that issue.
Your answer
Follow this Question
Related Questions
Reference Variables and Drag-And-Drop 0 Answers
Unity Best Practices - Cached Components 1 Answer
Improve Script Performance Physics 2 Answers
Reference Variables and Drag-And-Drop 0 Answers