Question

Hi I've been using Unity for a while and for the life of me I can still not tell the difference between OnCollisionStay and OnCollisionEnter. I'm assuming that OncollisionEnter is called when a rigidbody (like a ball) makes contact with another rigidbody/collider such as a wall. But when I look at the example for OnCollisionStay, I get completely confused. Even if its called once per frame, If I for example jump up in the air and hit a ceiling above me, is it still called? What exactly are the differences? Here is what the Unity documentation says and the code I was using.

"OnCollisionEnter is called when this collider/rigidbody has begun touching another rigidbody/collider."

"OnCollisionStay is called once per frame for every collider/rigidbody that is touching rigidbody/collider."

if(Input.GetKeyDown(KeyCode.W) && OnGround == True)
{
    rigidbody.velocity.y = jumpHeight;
}

onGround = false;

function OnCollisionStay()
{
    onGround = true;
}
Was it helpful?

Solution

It is really pretty simple. Let's assume that the collision starts, the colliders keep intersecting for a period of time (several frames), and after a while they separate again. The events then are:

  • OnCollisionEnter for the first frame only, and never again until after an OnCollisionExit
  • OnCollisionStay for the entire duration (all frames)
  • OnCollisionExit for the last frame only

Even if its called once per frame, If I for example jump up in the air and hit a ceiling above me, is it still called?

Sure it is. But then for that new collision. If there is a period in between where you're not colliding with anything however, you will not get OnCollisionStay events for that duration.

To get a deeper understanding of these events, it's perhaps best to create a simple demo scene in which you manually intersect two colliders, and have some text written to the console for the various events.

OTHER TIPS

Bart's answer is correct so this answer is more of an example of how you would use the two.

So OnCollisionEnter will fire 1 per collision case lets say for example a ball hitting a wall and OnCollisionEnter could maybe do some damage to the wall or destroy the wall. (Like breakout)

//Ball
#pragma strict

function OnCollisionEnter (col : Collision)
{
    if(col.gameObject.name == "Wall")
    {
        Destroy(col.gameObject);
    }
}

However in OnCollisionStay you would use that if you have a character with hit points that steps into a poison cloud and removes continuous hit points or removes incremental timed hit points as long as OnCollisionStay continues to fire after a given amount of time. (I'm thinking castlevania SOTH)

//PoisonGasCloud
#pragma strict
function OnCollisionStay(collisionInfo : Collision)
{

    collisionTime = Time.deltaTime;

    if ( collisionTime > 5)
    {
        hero.hp-=10;
    }
}

Note:I usually code in C# so my UnityScript might be a little off.

  • When collision start: OnCollisionEnter & OnCollisionStay
  • When collision continue: OnCollisionStay
  • When collision end: OnCollisionExit

Note 1: OnCollisionStay & OnCollisionExit will not be called simultaneously.

Note 2:OnCollisionEnter call before OnCollisionStay.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top