OnCollisionEnter and OnCollisionStay do not work properly

I am making a 3D first person game, and I ran into a very annoying and unpredictable issue: The “Grounded” variable I use to check if the player is touching the floor does not work as it should, even after following a tutorial (Physics).

Using the logs, I found the reason for it. It seems the methods OnCollisionEnter and OnCollisionStay are not being called when they should. They should always be called whenever the player’s collider (a capsule collider) is touching another collider (in this case, a box collider), yet they aren’t being. Instead, only when the player moves around does the Grounded variable turns true, and when the player stands still it becomes false after some milliseconds for some reason.

This is the code I am using:

    void OnCollisionEnter (Collision ObjectCollision)
    {
        print("enter");
        EvaluateCollision (ObjectCollision);
    }

    void OnCollisionStay (Collision ObjectCollision)
    {
        print("stay");
        EvaluateCollision (ObjectCollision);
    }

    void EvaluateCollision (Collision ObjectCollision)
    {
        for (int i = 0; i < ObjectCollision.contactCount; i++)
        {
            Vector3 ObjectNormal = ObjectCollision.GetContact(i).normal;

            if (ObjectNormal.y >= SlopeMinLimit)
            {
                Grounded = true;
            }
            else
            {
                Grounded = false;
            }
        }
    }

The Grounded variable is also automatically set to false at the end of FixedUpdate method (this should not be an issue however, it’s exactly the same approach used by the tutorial mentioned above and theoretically happens after the collision detections are calculated).

Any solutions?

It’s a bit of a statement to say these callbacks don’t work because your code doesn’t work; you’d think there’d be pitchforks out by pretty much most devs if that was the case.

Stay callbacks are only called when the Rigidbody(2D) is awake. They are not exactly cheap to call on every Rigidbody(2D) each update and pointless if they’re sleeping. Stop your character from sleeping if you must have them always happen.

1 Like

I was not aware of that. I don’t want the character to do unnecessary physics calculations, so I kept it sleeping, but added an if statement that only makes the player not grounded if they are not sleeping, that seems to fix the issue. Thanks for the help.

Yes, it mentions some of that detail in the docs for it here.

Glad you got it working.

1 Like