Quick answer: The most common cause is that one or both GameObjects involved in the collision are missing a Rigidbody component. Unity requires at least one of the two colliding objects to have a Rigidbody for OnCollisionEnter to fire.

Here is how to fix Unity oncollisionenter not called. Your player walks straight through enemies. Projectiles pass through walls. You added OnCollisionEnter to your script, the method signature looks correct, and there are no errors in the Console — but the callback never fires. This is one of the most common issues in Unity and it almost always comes down to a missing Rigidbody, an isTrigger mismatch, or a layer collision matrix misconfiguration.

The Symptom

You have a MonoBehaviour script attached to a GameObject with a Collider. You implemented OnCollisionEnter (or OnCollisionStay / OnCollisionExit), but the method is never called when your object comes into contact with another collider. There are no errors or warnings in the Console. The objects may visually overlap or pass through each other entirely.

In some cases, you might see the opposite problem: you expected OnTriggerEnter but implemented OnCollisionEnter, or vice versa. The two callback families are mutually exclusive for any given collider pair — a collider with isTrigger enabled will never produce OnCollisionEnter events.

What Causes This

Unity's physics system has strict requirements for collision callbacks to fire. The most common causes are:

The Fix

Step 1: Add a Rigidbody and verify isTrigger settings. Select each of the GameObjects involved in the collision. Make sure at least one has a Rigidbody component. Then check every Collider on both objects and ensure isTrigger is unchecked if you want OnCollisionEnter (or checked if you want OnTriggerEnter).

using UnityEngine;

public class ProjectileCollision : MonoBehaviour
{
    private void Start()
    {
        // Verify this object has a collider and a Rigidbody at runtime
        Collider col = GetComponent<Collider>();
        Rigidbody rb = GetComponent<Rigidbody>();

        if (col == null)
            Debug.LogError("No Collider found on " + gameObject.name);

        if (rb == null)
            Debug.LogWarning("No Rigidbody on " + gameObject.name +
                ". OnCollisionEnter requires at least one Rigidbody.");

        if (col != null && col.isTrigger)
            Debug.LogWarning("Collider isTrigger is ON. Use OnTriggerEnter instead.");
    }

    // This will only fire if:
    // 1. At least one object has a Rigidbody
    // 2. Neither collider has isTrigger enabled
    // 3. Both layers can collide in the Physics matrix
    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log("Collision with: " + collision.gameObject.name);
        Debug.Log("Contact point: " + collision.GetContact(0).point);
    }
}

Step 2: Check the Layer Collision Matrix. Go to Edit > Project Settings > Physics (or Physics 2D for 2D games). At the bottom you will see a matrix of checkboxes showing which layers can collide with which. Find the layers your two objects are on and make sure their intersection is checked.

using UnityEngine;

public class CollisionLayerDebugger : MonoBehaviour
{
    [SerializeField] private GameObject otherObject;

    private void Start()
    {
        if (otherObject == null) return;

        int layerA = gameObject.layer;
        int layerB = otherObject.layer;

        bool canCollide = !Physics.GetIgnoreLayerCollision(layerA, layerB);

        Debug.Log("Layer '" + LayerMask.LayerToName(layerA) +
            "' vs '" + LayerMask.LayerToName(layerB) +
            "' can collide: " + canCollide);

        if (!canCollide)
        {
            Debug.LogError("These layers are set to IGNORE each other. " +
                "Fix in Edit > Project Settings > Physics.");
        }
    }
}

Step 3: Verify collider placement and method signatures. If the Collider sits on a child object while the Rigidbody is on the parent, the callback fires on the parent. Also make sure you are using the correct callback for your physics dimension — OnCollisionEnter for 3D, OnCollisionEnter2D for 2D. The parameter type must match exactly.

using UnityEngine;

// For 3D physics: requires Collider + Rigidbody
public class Collision3DHandler : MonoBehaviour
{
    // Correct signature for 3D collisions
    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log("3D collision with " + collision.gameObject.name);

        // Access collision details
        ContactPoint contact = collision.GetContact(0);
        Debug.Log("Hit normal: " + contact.normal);
        Debug.Log("Impact force: " + collision.impulse.magnitude);
    }
}

// For 2D physics: requires Collider2D + Rigidbody2D
public class Collision2DHandler : MonoBehaviour
{
    // Correct signature for 2D collisions - note the "2D" suffix
    private void OnCollisionEnter2D(Collision2D collision)
    {
        Debug.Log("2D collision with " + collision.gameObject.name);

        ContactPoint2D contact = collision.GetContact(0);
        Debug.Log("Hit point: " + contact.point);
    }
}

// If collider is on a child, put the script on the Rigidbody parent
// OR forward the event from the child:
public class ChildCollisionForwarder : MonoBehaviour
{
    private void OnCollisionEnter(Collision collision)
    {
        // Forward to parent script
        var parentHandler = GetComponentInParent<Collision3DHandler>();
        if (parentHandler != null)
        {
            parentHandler.OnCollisionEnter(collision);
        }
    }
}

Here is a quick reference for the Unity collision matrix rules. Both objects need Colliders, and at least one needs a Rigidbody:

If you need collision detection between two kinematic bodies, consider using triggers (isTrigger = true) with OnTriggerEnter instead, or enable Contact Pairs Mode to Enable Kinematic Kinematic Pairs in your Physics settings.

Related Issues

See also: Fix: Unity Raycast Not Hitting Any Colliders.

See also: Fix: Unity Camera Not Rendering or Showing Black Screen.

At least one Rigidbody, matching isTrigger settings, and layers that can collide.