Mastering Unity Collision Events: OnCollisionEnter, Stay & Exit
Collision detection is one of the fundamental features of physics-based gameplay in Unity. Using Unity OnCollisionEnter, OnCollisionStay, and OnCollisionExit, developers can execute custom C# code whenever game objects physically touch, remain in contact, or separate from one another. These built-in collision events manage the complete interaction lifecycle, allowing you to build responsive gameplay mechanics like impact damage, sound effects, and ground detection.

The Collision Lifecycle: Enter → Stay → Exit
Together, these three events form the complete lifecycle of physical contact between objects:
- OnCollisionEnter: Triggers on the exact frame physical contact begins.
- OnCollisionStay: Triggers continuously on every physics step while contact persists.
- OnCollisionExit: Triggers on the exact frame physical contact ends.
1. What Is Is OnCollisionEnter in Unity?
OnCollisionEnter is invoked when two objects first make physical contact. It marks the beginning of contact between two Collider components participating in Unity’s physics engine.
Example: When a player character runs into a wall, OnCollisionEnter fires on the very first frame the player’s collider touches the wall’s collider.
Because it only fires once per collision event, it is ideal for single-instance actions such as:
- Playing impact sound effects or triggering particle visual effects.
- Dealing instant impact damage to a target or player.
- Instantiating impact decals (e.g., bullet holes or sparks).
- Registering projectile hits before destroying the projectile.
2. What Is OnCollisionStay?
OnCollisionStay is invoked continuously as long as two objects remain in contact. While OnCollisionEnter represents the start of a collision, OnCollisionStay persists throughout the interaction.
Common Use Cases:
- Dealing continuous damage over time (e.g., standing on lava, fire, or hazards in 2D platformer games).
- Checking if a character remains pressed against a wall or ground surface.
- Applying continuous physical forces (e.g., a conveyor belt or pushing heavy objects).
Performance Caution: Because
OnCollisionStayruns on every physics step (tied toFixedUpdate), avoid placing heavy computational logic or memory allocations (likeGetComponentorInstantiate) inside this method to prevent performance drops.
3. What Is OnCollisionExit?
OnCollisionExit represents the exact moment two objects separate and stop touching.
Common Use Cases:
- Stopping looping audio clips or particle effects initiated on initial impact.
- Resetting or canceling applied status effects (e.g., stepping out of a speed buff zone).
- Detecting when a character leaves a surface or detaches from a moving platform.
C# Code Example: Implementing Collision Events
To use collision callbacks, attach a C# script containing a MonoBehaviour class to a GameObject that has a Collider component.
using UnityEngine;
public class CollisionHandler : MonoBehaviour
{
// Fires ONCE when contact starts
private void OnCollisionEnter(Collision collision)
{
Debug.Log($"Started colliding with: {collision.gameObject.name}");
// Example: Accessing contact point data
ContactPoint contact = collision.contacts[0];
Vector3 position = contact.point;
}
// Fires EVERY PHYSICS FRAME while touching
private void OnCollisionStay(Collision collision)
{
Debug.Log($"Still touching: {collision.gameObject.name}");
}
// Fires ONCE when contact ends
private void OnCollisionExit(Collision collision)
{
Debug.Log($"Stopped colliding with: {collision.gameObject.name}");
}
}

Rigidbody Requirements: Why Aren’t My Collision Events Firing?
The most common reason developers fail to receive collision callbacks is an incorrect setup of Rigidbody and Collider components.
For collision events to fire, at least one of the interacting GameObjects must have a Rigidbody component attached, and neither collider can have Is Trigger checked.
| Object A Setup | Object B Setup | Will Collision Callbacks Fire? |
|---|---|---|
| Static Collider (No Rigidbody) | Static Collider (No Rigidbody) | No |
| Collider + Dynamic Rigidbody | Static Collider | Yes |
| Collider + Kinematic Rigidbody | Static Collider | No (unless Rigidbody A moves) |
| Collider + Dynamic Rigidbody | Collider + Kinematic Rigidbody | Yes |
Debugging Checklist:
- Ensure both GameObjects have active
Collidercomponents. - Ensure at least one object has an active
Rigidbody. - Verify
Is Triggeris unchecked on both colliders. - Check Unity’s Layer Collision Matrix in Project Settings → Physics to ensure both layers can interact.
Collision Events vs. Trigger Events
Unity separates physical interactions into two main categories:
- Physics Collisions (
OnCollisionEnter): Used when objects should physically block each other, bounce, or exert physical forces. - Trigger Events (
OnTriggerEnter): Used when objects should pass through each other while detecting overlap (e.g., coin pickups, checkpoint zones, or openable doors).
Physics Timing: Update vs. FixedUpdate
Collision callbacks occur during Unity’s physics simulation loop rather than the visual frame rendering loop.
Update()runs once per rendered frame (variable rate based on game FPS).FixedUpdate()runs on a fixed timer (defaulting to 0.02 seconds / 50Hz).
Because OnCollisionStay is tied to physics execution timing, always use Time.fixedDeltaTime instead of Time.deltaTime when calculating continuous physics calculations inside collision events.
Frequently Asked Questions (FAQ)
What is the difference between Collision and Collider in OnCollisionEnter?
In OnCollisionEnter(Collision collision), the Collision parameter contains detailed physics data about the impact, such as contact points, impact velocity, and the Collider attached to the other object. In contrast, trigger events only receive the Collider parameter.
Why is OnCollisionEnter not working in my Unity project?
OnCollisionEnter won’t fire if neither object has a Rigidbody attached, if Is Trigger is checked on either Collider, or if the interaction is disabled in the Layer Collision Matrix.
Does OnCollisionEnter work with Kinematic Rigidbodies?
Yes, but a Kinematic Rigidbody will only trigger OnCollisionEnter when colliding with a non-kinematic (Dynamic) Rigidbody, or if the Kinematic Rigidbody itself is explicitly moved through script/transform.
