Tips and Tricks: Unity GetComponent for accessing, storing, and modifying the behaviors of your objects
Introduction
Unity’s GetComponent method is probably the most commonly used method you will need outside of the lifecycle event methods. GetComponent retrieves a component that is attached to a GameObject and returns the component and all of its current properties.
GetComponent can be invoked three different ways. None of these methods are necessarily incorrect but they do offer different levels of type security. We certainly use this method a lot in our code and will be certain to point out which method we prefer. In this Tips and Tricks: Unity GetComponent we are going to show you how to use this method. As well as cover the best practices for writing performant code that does what you expect.
GetComponent of Type
The first way you can get a reference to a component is by using the GetComponent method with typeof method and providing the component’s type as an argument. This method is slightly longer and requires calling two methods to get the component while guaranteeing it is the correct type.
CapsuleCollider2D col = GetComponent(typeof(CapsuleCollider2D)) as CapsuleCollider2D;
GetComponent by name
Second, we can get a component by the name of the class. This takes a string argument. This is not type safe and could return a class with unexpected results. For safety we use the ‘as’ keyword to type cast the returned component into the expected component. We do not recommend using this implementation.
CapsuleCollider2D col = GetComponent("CapsuleCollider2D") as CapsuleCollider2D;
Using the Generic Method to Get a Component
As previously stated we use GetComponent a lot. The generic method is by far the easiest / quickest to type out. The generic method uses diamond notation to state that whatever is returned must be of that type. This makes it type safe without having to use other methods. We have included the ‘as’ keyword here as well since it is a best practice provided in the Unity documentation but it is not necessary.
CapsuleCollider2D col = GetComponent<CapsuleCollider2D>() as CapsuleCollider2D;
Why use GetComponent in Unity
The purpose for using GetComponent in your scripts, is to be able to modify the behavior. If, for instance, you want to slow a player’s speed when they walk through the mud, you would reference the player’s rigidbody. Once you have the rigidbody you can then increase the drag to bring out the feel of walking through mud.
Another reason could be to check if an object is of a certain type on collision. For example, if you have a tower defense game and an NPC enters the trigger for a tower. You can then add a check to see if it has an enemy component attached. If it does, the tower can attack. If not, it can ignore the object.
Cost of Searching for Components
Using GetComponent to locate and access components often brings up the talk of performance. While it is true that looking up a component uses resources, one lookup will not cause your frame rate to drop. By saying that I am not telling you to not try to optimize your code. It is good practice to limit the number of times GetComponent is called. What I am saying is that it is dependent on your individual use case.
Let us say, you are creating a platformer and to make your character jump you get a reference to the rigidbody. The jump button is only going to be pressed once every few frames, maybe a few more if you are like me and frantically trying to not fall in a pit. Looking up the player’s rigidbody in this case is not going to cause any issues.
In contrast, creating a shooter and accessing the rigidbody to add velocity to each bullet could be a problem. The player may end up firing 50 plus bullets per second. Assuming things are shooting back at you, you may need to multiply that number by a couple dozen.
Location of the GetComponent method also factors in. The update method is a prime place to overuse GetComponent methods. Continuing with the bullet example, Update occurs every time the frame refreshes. Want your game to run at 60 frames per second? That is 50 bullets per second for 24 players being looked up 60 times per second. We have now gone from 50 lookups to 72,000 and that is not counting anything other than getting the rigidbody of bullets.
Storing Components for Later Use
At this point you might be thinking “How do I stop all these performance hits?” The answer to that is simple, store the component in a variable. You can accomplish this with four different approaches.
First, by creating a public field, or for encapsulation purposes, a serialized private field, and assigning a value in the editor.
[SerializeField] private CapsuleCollider2D col;
Second, you can do the lookup in the start method, which only gets called once in the script’s lifecycle, and assign it to a private field.
private CapsuleCollider2D col;
void Start()
{
col = GetComponent<CapsuleCollider2D>();
}
Third, if the component is being accessed several times in one method, you can assign it to a local variable. This will be discarded when the method is finished executing.
void OnFire()
{
Rigidbody rb = GetComponent<Rigidbody>();
rb.AddForce(new Vector3(100,100,100),ForceMode.Impulse);
rb.useGravity = false;
}
Lastly, you can create a private field and check to see if the field is null before looking up the component. The field is then assigned during the first lookup. All further checks will bypass the lookup since the field is now assigned to.
private CapsuleCollider2D col;
void Update()
{
if(col == null)
{
col = GetComponent<CapsuleCollider2D>();
}
}
And now you are ready to use GetComponent in Unity scripts for your games. Thank you for stopping by. Stick around and check out more of our tutorials or posts like our piece on Using Unity AddComponent to Modify the Properties of Objects in Your Game. Also, leave a comment telling us what you liked or did not like about the tutorial. Was it easy to follow along? What do you want to learn next? As always, check out some of our published apps below.