"onCollisionEnter" not called when the two colliders collide

Colliders are components which define the shape of a GameObject for physical collisions. 

GameObjects are the foundational objects that represent characters, props, and all objects inside a scene – every object in your game is a GameObject

Note: GameObject and all other components are a part of the UnityEngine class.

The OnCollisionEnter function is called whenever a GameObject collides with another one.

Syntax

void OnCollisionEnter(Collision collision)
{
Debug.Log(collision.name);
}

onCollisionEnter method takes only one parameter of type Collision which stores the information about the collision events. It includes the collision direction, the point of contact, the name of the GameObject, relativeVelocity, and much more.

Major reasons

There are several reasons for the OnCollisionEnter method not being called when the two objects collide.

For the solutions explained below:

  • The blue ball is labeled "Spehere 1".

  • The black ball is labeled "Sphere 2".

  • The cube at the bottom is the floor.

The Rigidbody property is not set

One of the GameObjects must have a Rigidbody component for the onCollisionEnter method to work. The collision occurs only when the dynamic colliderMoveable objects interacts with the static colliderImmovable objects, or another dynamic collider.

Solution: You need to make sure that the GameObjects have a Rigidbody component attached.

In our case, only one of the GameObjects has a Rigidbody component (the floor). The onCollisionEnter method will not be called because Sphere 2 will not move from its position to collide with the floor.

Ony Sphere 1 has the Rigidbody component attached
Ony Sphere 1 has the Rigidbody component attached

As shown above, only Sphere 1 (the blue ball), has the RigidBody component attached.

Demonstration

How to setup the Rigidbody component

  • Select the GameObject

  • In the Inspector menu, select "Add Component"

  • Select Rigidbody

Setting up Rigidbody component
Setting up Rigidbody component

The script containing the onCollisionEnter() method is attached to both Sphere 1 and the floor, so it gets called for both objects as the output shows in the console in the picture below.

Both spheres are set to have Rigidbody component
Both spheres are set to have Rigidbody component

Demonstration

Note: The method will be called even if the object doesn't have a Rigidbody component attached but something has to collide with it first.

The "Is Trigger" property is not set

If you set the "Is Trigger" property, the onTriggerEnter() method will be called instead of the onCollisionEnter() method. In this case, the colliders will move freely through each other instead of colliding. 

Solution: Make sure to uncheck the Is Trigger property if you want the GameObjects to collide.

Note:

  • If you want your colliders to interact physically with the world, "Is Trigger" property should be unchecked.

  • If you want your collider to act as a trigger for an event when something enters it, "Is Trigger" property should be checked.

Here, Sphere 2 is has the "Is Trigger" property enabled. It will pass through Sphere 1 and the onCollisionEnter() method will not be called.

Sphere 2 is set to have Is Trigger property
Sphere 2 is set to have Is Trigger property

Demonstration

The "Is Kinematic" property is set

The GameObject becomes kinematic if this property is set to true. It means that the object will not be affected by any forces applied to it. This makes the case similar to when the Rigidbody component is not attached to the object. It will not move and hence the collision will never occur. 

Solution: If you want the collisions to happen, make sure to set the "Is Kinematic" property to false. 

Sphere 2 (the black ball) has the "Is Kinematic" property enabled. It will not show any motion whereas Sphere 1 (the blue ball) falls to the floor and calls its onCollisionEnter() method.

Sphere 2 has the Is Kinematic property enabled
Sphere 2 has the Is Kinematic property enabled

Demonstration

If we set both of the GameObjects to have Is Kinematic property, the objects will not collide and hence there will be no motion as shown below.

Incorrect or missing scripts

Solution: Make sure that the GameObject is attached with its relevant script, and the methods are written correctly.

Note: Make sure to add the onCollisionEnter method outside the Update() function.

How to add scripts

  • Click on the Add Component

  • In the search bar, type the name of the C# script and hit enter.

How to add C# script as a component
How to add C# script as a component

If the scripts are not attached to the GameObjects, the methods specified in the script will not be called. In the demonstration below, both of the objects collide with each other. But the onCollisionEnter() method is not called.

Layer based collision settings

Unity allows you to specify which specific layers can interact with each other. If the layers of two specific GameObjects are not set to interact with each other, the onCollisionEnter() method will not be called. 

Solution: Check for the layer based settings in the Physics Manager.

How to check layer based settings

  1. Select Edit

  2. Go to Project Settings

  3. Select Physics

  4. Scroll down and check Enable All

1 of 3

Every GameObject has the Layer set to Default. You can choose which specific layers can interact with each other (check or uncheck the layers) by following the method shown above.

GameObject layer
GameObject layer

Demonstration

If all of the layers are disabled, the GameObjects will not interact with each other as shown below.

onCollisionEnter() is called when both the GameObjects have the Rigidbody component, C# script attached and furthermore, have the "Is Trigger" and "Is Kinematic" properties set to false.

Copyright ©2024 Educative, Inc. All rights reserved