Search Unity

OnCollisionEnter getting called twice?!

Discussion in 'Scripting' started by Marscaleb, May 16, 2021.

  1. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,037
    I've discovered an odd bug; it seems that sometimes OnCollisionEnter is getting called twice on the same frame. I'm wondering if anyone has noticed this effect before.

    I'm seeing this with some rocks the player throws and then the rocks shatter when they hit something; the function instantiates a shatter effect and then destroys the gameobject. If I throw them at another rock, it called OnCollisionEnter twice in the same object, spawning two of my shatter effects.
    Now at this point the rock that is thrown has only one active collider: a sphere collider which is on a layer that only connects with default (world), enemies, and others of it's layer.
    The rock that it hits has this same sphere collider and another capsule collider on the default layer (which gets disabled once the player picks up the rock.)
    As far as I can tell, the thrown rock sometimes manages to call OnCollisionEnter on the same frame separately for both of those colliders. If I disable the sphere's collision layer from colliding with itself I don't get this happening anymore.

    Is this... normal? Should I be submitting a bug report?
    This isn't what I would expect to be happening; I was under the impression that all the colliders on a child object act as one combined collider.
    If this is normal behavior, then how am I supposed to handle multiple collision calls occurring on the same object on the same frame? I can only imagine this causing more problems with more complex things like characters.
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    Add a bool to the code. Set it to true when the collision happens and the explosion happens. Check against the bool in ONCollisionEnter to see if it's true. If it is, do nothing.
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    If you are truly moving 100% of your Colliders and Rigidbodies during FixedUpdate() and also only moving them by using the Rigidbody.MovePosition() / .MoveRotation call, then this might be a bug. This also presupposes you have precisely two colliders coming together.

    But if you move even one collider or rigidbody with Transform.Translate(), Transform.Rotate() or by setting the .position (or rotation) directly, or by animation or other mechanism, all bets are off and the physics system is liable to malfunction, since you have essentially left it out of the discussion and now it has to play catch-up and solve what might be a very intractable collision problem that someone else got it into.
     
  4. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,037
    I moved the rock by applying a velocity to it. That was many frames before the collision occurred.
    At the time of impact, the only thing moving the collider is Unity's internal physics calculations.