Summary
GetComponent<T>() searches for a component of type T on the same GameObject and returns it, or null if the component is not found. It is the standard way to access Unity components — such as Rigidbody2D, Collider2D, or Animator — from inside a script. Because GetComponent performs a search at runtime, it should be called once in Start and the result cached in a field, rather than called every frame in Update.
Key ideas
Generic syntax: GetComponent<T>() where T is the component type. Returns null if the component is not present on the GameObject.
Cache in Start: Calling GetComponent in Update runs the search every frame — an unnecessary performance cost. Store the result in a private field during Start and use the field in Update.
Null check: If the component is missing, the returned reference is null. Calling any method or property on null throws a NullReferenceException. Validate the result in Start using Debug.LogError so the problem is visible immediately.
Public read-only accessors: When another script needs to read a value from this script (such as the current score), expose it through a public method rather than a public field. This lets the owning script control writes while still allowing reads. The expression-bodied shorthand (=>) is idiomatic in Unity reference scripts.
In practice
Caching a component in Start:
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private float speed = 5f;
private Rigidbody2D rb; // cached reference
void Start()
{
rb = GetComponent<Rigidbody2D>();
if (rb == null)
Debug.LogError("[" + gameObject.name + "] Rigidbody2D not found!");
}
void Update()
{
float h = Input.GetAxisRaw("Horizontal");
// Use the cached reference — no search every frame
rb.velocity = new Vector2(h * speed, rb.velocity.y);
}
}Null check before use:
void Start()
{
Animator anim = GetComponent<Animator>();
if (anim != null)
{
anim.SetBool("IsRunning", false);
}
else
{
Debug.LogWarning("[" + gameObject.name + "] No Animator found — skipping setup.");
}
}Public read-only accessors:
// Other scripts read score and health via methods, not directly
public int GetScore() => score;
public int GetHealth() => health;
public bool IsGameOver() => isGameOver;// Calling script reads without being able to write
int currentScore = gameManager.GetScore();GetComponent vs Inspector reference
| Inspector reference | GetComponent | |
|---|---|---|
| How set up | Drag-and-drop in Inspector at design time | Searched at runtime via code |
| When to use | Permanent connections between named scene objects | Accessing components on the same GameObject |
| Performance | Free at runtime (direct reference) | Small cost — cache in Start, not Update |
| Risk | NullReferenceException if not assigned | NullReferenceException if component missing |
See unity-inspector-references for the Inspector reference pattern.
Gotchas
GetComponentonly searches the same GameObject. To find a component on another object, useotherGameObject.GetComponent<T>(), or useGetComponentInChildren<T>()/GetComponentInParent<T>().- Always use
Debug.LogError(notDebug.Log) in a null-check failure insideStart— the red colour makes it immediately visible in the Console. GetComponentis case-sensitive and type-safe. A typo in the type name is caught at compile time.
Related
- monobehaviour-lifecycle —
Startis where caching belongs - unity-inspector-references — the alternative way to connect scripts
- unity-rigidbody2d — the most common component fetched via
GetComponent - unity-animator-scripting —
GetComponent<Animator>()usage