
Recently, I see too many YouTube videos, tutorials, and questions in Unity groups where people are overusing GetComponent methods in their code. Time to talk about why you shouldn’t use it! Or at least use it sparingly.
Why am I bothering about that? Because I’m doing code reviews, and I just had enough of it. ?
YouTubers, tutors, Unity, and other content creators – YOU ARE RESPONSIBLE FOR MAKING PEOPLE DO BAD THINGS!
Now let’s try to fix it. ?
Why so dramatic? ?
As I said earlier, more and more people are using GetComponent methods in a bad way.
Unity’s documentation is a great resource, and I have to acknowledge it. But the problem is that people use examples from documentation in their code.
And the worst part is that this mistake can be easily avoided. Whenever someone explains what GetComponent is, he should add a disclaimer with BIG LETTERS when it’s fine to use it and when you shouldn’t!
So yeah, I have a problem with that, because later I have to deal with GetComponents in the code, which I really don’t like!

What’s the issue with GetComponent? ?
The GetComponent and all other methods like it in Unity are methods to find a component attached to GameObjects.
Each of these methods is going through a list of attached components. Each time it’s used.
This has real performance implications, and as a programmer, you should optimize your solutions!
Why I shouldn’t use it? ⛔️
As I already mentioned, whenever you call the GetComponent method, your code runs through a list of attached components.
I’m fine with this method when you are initializing your object or when you are running checks to detect what entered trigger.
But for God’s sake, NEVER do it in the Update or any other place which is called in the loop!
It’s killing me when I see it! There should be a special place in hell for people doing that in their code.

How can I do BETTER? ??
There are many ways you can avoid using so many GetComponents in your code.
- Call it once to get component before using it.
DON’T
using UnityEngine; using UnityEngine.UI; /// <summary> /// Bad example, don't do it like that! /// </summary> public class DontDoThat : MonoBehaviour { /// <summary> /// Set start values. /// </summary> void Start() { // Continuously getting component. Don't do it. gameObject.GetComponent<Text>().text = "Hello!"; gameObject.GetComponent<Text>().color = Random.ColorHSV(); gameObject.GetComponent<Text>().fontSize = Random.Range(14, 32); } }
DO
using UnityEngine; using UnityEngine.UI; /// <summary> /// Good example, you can do it like that! /// </summary> public class DoThat : MonoBehaviour { /// <summary> /// Set start values. /// </summary> void Start() { // Get component before you do something with it! var textComponent = gameObject.GetComponent<Text>(); // Assign values. textComponent.text = "Hello!"; textComponent.color = Random.ColorHSV(); textComponent.fontSize = Random.Range(14, 32); } }
- Save references in the variable.
DON’T
using UnityEngine; using UnityEngine.UI; /// <summary> /// Bad example, don't do it like that! /// </summary> public class DontDoThat : MonoBehaviour { /// <summary> /// Set start values. /// </summary> void Start() { // Continuously getting component. Don't do it. gameObject.GetComponent<Text>().text = "Hello!"; gameObject.GetComponent<Text>().color = Random.ColorHSV(); gameObject.GetComponent<Text>().fontSize = Random.Range(14, 32); } /// <summary> /// Update values each frame. /// </summary> void Update() { // Continuously getting component in each frame! Big NO NO NO! gameObject.GetComponent<Text>().text = "Hello! Time: " + Time.realtimeSinceStartup; gameObject.GetComponent<Text>().color = Random.ColorHSV(); gameObject.GetComponent<Text>().fontSize = Random.Range(14, 32); } }
DO
using UnityEngine; using UnityEngine.UI; /// <summary> /// Good example, you can do it like that! /// </summary> public class DoThat : MonoBehaviour { // Reference to the component which you can use in your code. private Text textComponent; /// <summary> /// Initialize component with references. /// </summary> void Awake() { // Get component before you do something with it! textComponent = gameObject.GetComponent<Text>(); } /// <summary> /// Set start values. /// </summary> void Start() { // If you don't want to write Awake method, you can still get component reference here // textComponent = gameObject.GetComponent<Text>(); // Set start values for the component. textComponent.text = "Hello!"; textComponent.color = Random.ColorHSV(); textComponent.fontSize = Random.Range(14, 32); } /// <summary> /// Update values each frame. /// </summary> void Update() { // Update values for the component. textComponent.text = "Hello! Time: " + Time.realtimeSinceStartup; textComponent.color = Random.ColorHSV(); textComponent.fontSize = Random.Range(14, 32); } }
- You can skip using GetComponent and assign references in the editor.
DO
using UnityEngine; using UnityEngine.UI; /// <summary> /// Good example, you can do it like that! /// </summary> public class DoThat : MonoBehaviour { // Reference to the component which you can use in your code. [SerializeField] private Text textComponent; /// <summary> /// Set start values. /// </summary> void Start() { // Set start values for the component. textComponent.text = "Hello!"; textComponent.color = Random.ColorHSV(); textComponent.fontSize = Random.Range(14, 32); } /// <summary> /// Update values each frame. /// </summary> void Update() { // Update values for the component. textComponent.text = "Hello! Time: " + Time.realtimeSinceStartup; textComponent.color = Random.ColorHSV(); textComponent.fontSize = Random.Range(14, 32); } }
Just don’t forget to assign that reference!

- For prefabs use reference to component rather than a GameObject.
DON’T
using UnityEngine; using UnityEngine.UI; /// <summary> /// Bad example, don't do it like that! /// </summary> public class DontDoThat : MonoBehaviour { // Reference to the prefab as GameObject. Whenever you can you should use the type of specific component you are interested in. public GameObject textPrefab; /// <summary> /// Set start values. /// </summary> void Start() { CreatePrefabInstance(); } /// <summary> /// Creating prefab instance. /// </summary> void CreatePrefabInstance() { // Creating prefab instance as GameObject var instance = Instantiate(textPrefab); // Continuously getting component. Don't do it. instance.GetComponent<Text>().text = "Hello!"; instance.GetComponent<Text>().color = Random.ColorHSV(); instance.GetComponent<Text>().fontSize = Random.Range(14, 32); } }
DO
using UnityEngine; using UnityEngine.UI; /// <summary> /// Good example, you can do it like that! /// </summary> public class DoThat : MonoBehaviour { // Reference to the prefab as Text component. [SerializeField] private Text textPrefab; /// <summary> /// Set start values. /// </summary> void Start() { CreatePrefabInstance(); } /// <summary> /// Creating prefab instance. /// </summary> void CreatePrefabInstance() { // Creating prefab instance and receiving reference to the Text component. var textInstance = Instantiate(textPrefab); // Update values for the component. textInstance.text = "Hello!"; textInstance.color = Random.ColorHSV(); textInstance.fontSize = Random.Range(14, 32); } }
And by using these few methods, you can save my (and probably others) sanity. ?
How about the performance
If this post didn’t convince you already, let’s speak about performance implications.
GetComponent method is resource-intensive. And those resources you can put into something else, like rendering more frames!
If you don’t believe me, you can go to my post about using Profiler and you can see it yourself.
I used the Transform component, which every GameObject has, and a run a quick test. I’ve called 100k times GetComponent<Transform>, transform property (underneath there is also GetComponent method), and cached transform property.

Can you see my problem here?
Summary? ?

So that’s my rant about GetComponents in people’s code. I hope all of you take it to heart and won’t need it to do another one in the future! ?
Please share this post with someone you care about, and you want to help them make a better game!
What else people do that drives you insane? Let me know in the comment section below!
And if you want to be notified about future content on my blog, you can sign up for my newsletter!
Thanks for reading, and see you next time! ?
Great post Patryk!
I personally like to use
because it works like Lazy, it only does GetComponent once only when object is being used and is pretty clean.
I really like your solution! 🙂
You still run the check every time you access the field, in exchange for a single line of code.
The shorthand looks cool, but it’s still better to store the ref during initialization.
If you are using the component once, then this is a good solution. However, it would get loud if you had more than one line of this.
Why no benchmarks? Seems like a necessity when comparing different methods based on their performance.
Awesome post.
Totally agree! , keep the good posts
??
Don’t use GetComponent inside Awake method. Start is better place for it.
Why is it? Never had any troubles in Awake
I just started learning Unity weeks ago, since now i’ll avoid the unnecessary get components like the plague
Usually, in C#, a private variable that is initialized on startup and then used in multiple methods needs an underscore in front of its name.
For example, textComponent would be _textComponent. It is an easy way to understand that the variable is not being created inside the method or being passed into the method.
I’m not sure how many people do this in the Unity community though.
Does it slow the code ? or just personal prefrence
Who does that… like really. I would imagine only noobs do this haha, but I chuckled 😀 thanks for that.
Have you looked at the actual code generated? I’ll bet the compiler takes care of the redundancy in the repeated calls to GetComponent.