Unity Term Book
Physics

Trigger

A Trigger is a Collider in ghost mode — it detects enter, stay, and exit without a physical push-back, used for checkpoints, pickups, and automatic doors.

Imagine...

A Trigger is like a supermarket door sensor. The door does not shove you back when you step in — it only notices you and opens. No physical force, just a signal: "someone entered." In Unity, `OnTriggerEnter` is that signal — fired the moment a character touches the zone, so you can open a door, heal, start a cutscene...

The concept in detail

A Trigger is a normal Collider with the Is Trigger checkbox on. Once enabled, the Collider becomes pass-through — bodies walk through it with no push-back. Unity instead fires three callbacks: OnTriggerEnter (on enter), OnTriggerStay (every frame while inside), and OnTriggerExit (on leave).

For a trigger to fire, at least one of the two objects must have a Rigidbody. That is the classic miss — two static objects (no Rigidbody) never trigger each other. If you do not want gravity, set isKinematic = true.

Triggers cover a lot of ground: checkpoint (save position on walk-through), pickup zone (collect an item), enemy detection (AI awareness radius), damage zone (fire, acid), cutscene trigger (story beat). None of these need real physics — only “who entered this volume?”

In Unity 2D the matching callbacks are OnTriggerEnter2D, OnTriggerStay2D, OnTriggerExit2D — same shape, but they receive a Collider2D instead of a Collider.

Trigger vs Collision lifecycle

Trigger (isTrigger = true)

OnTriggerEnter

First frame of contact

OnTriggerStay

Every frame while still inside

OnTriggerExit

Last frame when leaving

✅ Walk through — no contact force

Collision (isTrigger = false)

OnCollisionEnter

First frame of impact

OnCollisionStay

Every frame while touching

OnCollisionExit

When they separate

🔒 Blocked — a physical contact force

⚠️ Hard requirement:

At least one of the two objects must have a Rigidbody (or Rigidbody2D) or trigger/collision will never fire.

Hands-on steps

1

Create a trigger volume

Create an empty GameObject, Add Component → BoxCollider, check "Is Trigger". Size it to the zone you want.

2

Give the moving body a Rigidbody

The character or projectile needs a Rigidbody. If gravity should not apply, set isKinematic = true.

3

Write the trigger handler

Add a script with OnTriggerEnter(Collider other) on the trigger object or the moving body.

4

Filter with Layers

Check other.gameObject.layer or CompareTag so you only react to the objects you care about.

5

Debug with Gizmo color

Triggers draw cyan (collisions draw green). Add OnDrawGizmos if you need extra debug drawing.

Interactive simulator

Use the ← → arrow keys (or the buttons below) to walk the character through trigger zones.

Trigger Zone

Walk the character into a trigger zone...

Code example

Basic

Simple pickup: collect a coin when the player enters the trigger.

using UnityEngine;

// Attach this to a Coin with a Collider that has isTrigger = true
public class CoinPickup : MonoBehaviour
{
  public int value = 10;
  public AudioClip pickupSound;

  void OnTriggerEnter(Collider other)
  {
      // Only react to the Player
      if (!other.CompareTag("Player")) return;

      // Award points via GameManager
      GameManager.instance.AddScore(value);

      // Play a pickup sound
      AudioSource.PlayClipAtPoint(pickupSound, transform.position);

      // Remove the coin from the scene
      Destroy(gameObject);
  }
}

Code example

Advanced

Timed hazard: deal damage every frame while inside, stop on exit.

using UnityEngine;
using System.Collections;

// A fire zone that damages while you stand in the trigger
public class DamageZone : MonoBehaviour
{
  public float damagePerSecond = 10f;
  public LayerMask damageable;

  Coroutine damageRoutine;
  PlayerHealth currentTarget;

  void OnTriggerEnter(Collider other)
  {
      if ((damageable.value & (1 << other.gameObject.layer)) == 0) return;

      currentTarget = other.GetComponent<PlayerHealth>();
      if (currentTarget != null)
          damageRoutine = StartCoroutine(DamageLoop());
  }

  void OnTriggerExit(Collider other)
  {
      if (damageRoutine != null)
      {
          StopCoroutine(damageRoutine);
          damageRoutine = null;
          currentTarget = null;
      }
  }

  IEnumerator DamageLoop()
  {
      while (true)
      {
          currentTarget.TakeDamage(damagePerSecond * Time.deltaTime);
          yield return null; // Wait one frame
      }
  }
}

📌 Quick recap

  • isTrigger=true → walk through, receive events
  • At least one side must have a Rigidbody
  • CompareTag() is faster than comparing strings directly
  • OnTriggerStay runs every frame — watch the cost
  • Use a LayerMask to filter objects cheaply

⚠️ Common mistakes

  • ❌ Trigger never fires even though isTrigger is on

    Neither object has a Rigidbody

    ✅ Add a Rigidbody (isKinematic=true if needed) to the moving body

  • ❌ Calling Destroy(other.gameObject) inside OnTriggerStay

    Errors because the object is destroyed mid physics loop

    ✅ Destroy in OnTriggerEnter and null-check first