Collision Detection In Unity

Last Updated : 4 May, 2026

Collision detection is the system that tells you when two GameObjects touch each other. When a collision happens, Unity automatically calls special methods in your scripts, allowing you to respond like reducing health, playing a sound, or destroying an object.

Collision Event Methods

Unity provides three collision events that you can use in your scripts:

  • OnCollisionEnter: Best for most cases (damage, item pickup, death).
  • OnCollisionStay: Use for continuous effects (melting, burning).
  • OnCollisionExit: Use for leaving detection (stopping sound effects).

Example

C#
public class Player : MonoBehaviour
{
    void OnCollisionEnter(Collision collision)
    {
        // Runs ONCE when two objects first touch
        Debug.Log("Collision started with: " + collision.gameObject.name);
    }
    void OnCollisionStay(Collision collision)
    {
        // Runs EVERY FRAME while objects remain touching
        Debug.Log("Still touching...");
    }
    void OnCollisionExit(Collision collision)
    {
        // Runs ONCE when objects separate
        Debug.Log("Collision ended");
    }
}

Collision Parameter

It gives you useful information about the impact:

  • collision.gameObject: The object we collided with
  • collision.relativeVelocity: Speed of impact (high = hard hit)
  • collision.contacts[0].point: World position of collision

Requirements for Collision Events to Fire

For OnCollisionEnter/Stay/Exit to work:

  • Both objects must have Collider components.
  • At least one object must have a non-kinematic Rigidbody.
  • Neither Collider should be marked as "Is Trigger".

Not working? Check these:

  • Is Rigidbody missing? Add one.
  • Is "Is Trigger" checked? Uncheck it (use triggers for overlap detection).
  • Is Rigidbody kinematic? Set to non-kinematic.

Practical Examples

Example 1: Player takes damage when hitting enemy

C#
void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("Enemy"))
    {
        health -= 10;
        Debug.Log("Hit! Health: " + health);
    }
}

Example 2: Bullet destroys on impact

C#
void OnCollisionEnter(Collision collision)
{
    // Ignore collision with shooter
    if (collision.gameObject == shooter) return;
    Destroy(gameObject);  // Destroy bullet
}

Example 3: Play sound based on impact speed

C#
void OnCollisionEnter(Collision collision)
{
    float volume = collision.relativeVelocity.magnitude / 10;
    AudioSource.PlayClipAtPoint(impactSound, transform.position, volume);
}

Collision vs Trigger

FeatureCollisionTrigger
Method to UseOnCollisionEnter()OnTriggerEnter()
Physical InteractionObjects physically collide (block each other)Objects do not block (only overlap detection)
Is Trigger OptionNot checkedMust be checked
Use CaseSolid objects (walls, floors, enemies)Detection only (coins, checkpoints, pickups)

Performance Considerations

  • Keep collision code lightweight as it is called frequently.
  • Avoid Find() or heavy operations inside collision methods.
  • Use tags or layers instead of GetComponent when possible (faster).
  • Cache components in Start() instead of getting them in collision.

Common Mistakes

  • Using OnTriggerEnter when objects need to physically block - Use OnCollisionEnter instead
  • Forgetting Rigidbody: Collision events won't fire
  • Moving objects via Transform instead of physics: Causes inconsistent collisions
  • Checking collision.gameObject.tag == "Enemy" (expensive) – Use CompareTag() instead
Comment
Article Tags:

Explore