Search Unity

Intercept collision callback? (2D physics)

Discussion in 'Scripting' started by Bankler, Oct 27, 2014.

  1. Bankler

    Bankler

    Joined:
    Apr 10, 2012
    Posts:
    66
    In an older Unity version, if I had a hierarchy of a parent and a child, and both had colliders on them, and both had a script component on them, OnCollisionEnter2D was only called on the outermost (ie the child) object if that specific collider was hit. Only if the child did not implement OnCollisionEnter2D, the callback was fired on the parent. This made a lot of sense.

    Using this, I could have a parent holding a shield object (that had a collider and a script implementing OnCollisionEnter2D), which would then intercept the contacts (in this case, shielding the parent from taking damage, instead only dealing damage to the shield).

    However, since then, this seems to have changed. Currently, OnCollsionEnter2D seems to be called in the whole hierarchy up to the parent.

    First of all, is this even how it's supposed to work?

    Secondly, for a workaround, how can I get the behaviour described in the first part of this post? (ie, intercepting the OnCollisionEnter2D so it only gets fired on the child, if the child is hit)

    Disclaimer: Reservation for that my memory may fail me, that I may have confused how 2D vs 3D works and all that good stuff. :)
     
  2. Bankler

    Bankler

    Joined:
    Apr 10, 2012
    Posts:
    66
    Ok, I might have found it myself. It seems adding a kinematic Rigidbody2D to the child does the trick. (This might have been the case in earlier Unity versions as well, I'm honestly not sure)

    EDIT: No, don't do this.
     
    Last edited: Oct 30, 2014
  3. Bankler

    Bankler

    Joined:
    Apr 10, 2012
    Posts:
    66
    Continuing my little monologue here. :)

    Ok, it turned out adding a childed kinematic Rigidbody2D was a bad idea. While it indeed intercepted the collision callback, it resulted in all sorts of unwanted behaviour as well (for instance, something colliding with the child did not result in a pushing force at all).

    So, instead of blocking out the callback, I chose to receive it and then filter it by checking if the collision actually happened on the main object, or if it happened on a child.

    void OnCollisionEnter2D(Collision2D collision)
    {
    //contactCollider is the collider on THIS destructible's hierarchy that something is colliding with.
    Collider2D contactCollider = collision.contacts[0].otherCollider;

    if(contactCollider != null && collider2D != null)
    {
    //Something is merely colliding with one of our children, so ignore this.
    if(!ReferenceEquals(contactCollider, collider2D))
    {
    print("Protected by shield");
    return;​
    }​
    }​
    }