U
09 / 22 · 9 min
FAQ

Collisions and triggers: why the event never fires

the short answer

Why are OnCollisionEnter and OnTriggerEnter never called?

Both objects need a collider, and one of them needs a Rigidbody: a non-kinematic one for OnCollisionEnter, any one — kinematic included — for OnTriggerEnter. Then check the method name and its parameter, that the script sits on the object holding the collider, and that the two layers are still ticked in the Layer Collision Matrix.

Two objects touch on screen and your method does not run. Nothing in the Console, no error, no warning — Unity simply never called it. There are only six reasons for that, and you can walk through them in about a minute.

First: which of the two events do you want?

✓ OnCollisionEnter

solid hits solid

The two objects cannot pass through each other. Use it when the hit is physical: a crate knocked over, a ball off a wall. You are handed a Collision, which carries the contact points and the impact velocity.

✓ OnTriggerEnter

something enters an area

The two objects pass straight through each other and you are only told that it happened. Use it for coins, doorways, damage zones, the reach of a sword. You are handed a Collider: what entered, nothing about the impact.

The six checks, in order

  1. 1

    A Rigidbody somewhere. Unity only reports a touch when physics is watching one of the two objects. Collision events need a Rigidbody that is not kinematic on at least one side; trigger events need a Rigidbody on at least one side, and a kinematic one is fine. Two objects that both just sit there report nothing.

  2. 2

    The name and the parameter. OnTriggerEnter(Collider other) and OnCollisionEnter(Collision collision) — spelt exactly like that. Unity finds these by name, so onTriggerEnter, or a Collider2D in a 3D scene, compiles perfectly and is never called.

  3. 3

    The script is on the right object. The message goes to the GameObject that holds the collider, and to the GameObject that holds the Rigidbody the collider belongs to. A script one level up from both of those hears nothing.

  4. 4

    Both colliders exist and are enabled. The Inspector is the fastest check: press Play, walk into the thing, and watch whether the two collider outlines actually meet in the Scene view. A collider left at its default size often sits inside the model.

  5. 5

    The two layers are allowed to meet. Edit▸Project Settings▸Physics holds the Layer Collision Matrix. One unticked square there and the two objects ignore each other completely — no collisions, no triggers, no message.

  6. 6

    2D and 3D never meet. Collider2D and Collider are two separate physics engines living in the same scene. A 2D collider will never touch a 3D one, and the 2D events are the ones ending in 2D.

A trigger that works, and a collision that works

Coin.cs — on the coin: a trigger collider, no Rigidbody needed on the coin itself
using UnityEngine;

// The coin sits still, so the Rigidbody lives on the player instead.
[RequireComponent(typeof(Collider))]
public class Coin : MonoBehaviour
{
    public int value = 1;

    void Reset()
    {
        // Runs when the component is added: tick Is Trigger for whoever forgets.
        GetComponent<Collider>().isTrigger = true;
    }

    void OnTriggerEnter(Collider other)
    {
        // Anything can walk in here — check who it was before scoring.
        if (!other.CompareTag("Player")) return;

        // Wire this into whatever keeps your score.
        Debug.Log($"+{value}");
        Destroy(gameObject);
    }
}
Crate.cs — on the crate: a solid collider and a Rigidbody that physics may push
using UnityEngine;

[RequireComponent(typeof(Rigidbody), typeof(Collider))]
public class Crate : MonoBehaviour
{
    public AudioSource thud;

    void OnCollisionEnter(Collision collision)
    {
        // Collision carries the impact: a light nudge should not sound like a crash.
        if (collision.relativeVelocity.magnitude < 2f) return;

        thud.Play();
    }
}

Two more that catch people out

  • A CharacterController is not a Rigidbody. It never calls OnCollisionEnter — it calls OnControllerColliderHit instead — but it does set off triggers as it moves, which is why a character who cannot push crates can still pick up coins.

  • Something fast enough skips straight through a thin wall between two frames. On that Rigidbody, set Collision Detection to Continuous, and give the wall some thickness while you are there.

  • Moving a Rigidbody by writing transform.position teleports it, and a teleport has no path for physics to test. Move it with Rigidbody.MovePosition, or with velocity, and the touches come back.

the lesson that builds this

Projectiles, damage and VFX

This post is a standalone recipe. In the course, the same thing is built as part of the one project that runs through all five tabs — Character & Combat, lesson 05.