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 referenceGetComponent
How set upDrag-and-drop in Inspector at design timeSearched at runtime via code
When to usePermanent connections between named scene objectsAccessing components on the same GameObject
PerformanceFree at runtime (direct reference)Small cost — cache in Start, not Update
RiskNullReferenceException if not assignedNullReferenceException if component missing

See unity-inspector-references for the Inspector reference pattern.


Gotchas

  • GetComponent only searches the same GameObject. To find a component on another object, use otherGameObject.GetComponent<T>(), or use GetComponentInChildren<T>() / GetComponentInParent<T>().
  • Always use Debug.LogError (not Debug.Log) in a null-check failure inside Start — the red colour makes it immediately visible in the Console.
  • GetComponent is case-sensitive and type-safe. A typo in the type name is caught at compile time.