Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to use Collision2D.GetContacts instead of Collision2D.contacts

Discussion in 'Physics' started by eighto, Oct 29, 2017.

  1. eighto

    eighto

    Joined:
    Apr 27, 2013
    Posts:
    32
    Code (CSharp):
    1. void OnCollisionEnter2D(Collision2D collision)
    2. {
    3.     if (collision.contacts[0].normal.x > 0) //do stuff
    4. }
    5.  
    This has always worked fine until recently (I think after updating to 2017.2, it was working in 2017.1). Now it gives me an IndexOutOfRangeException. The contacts array is now always empty. I can't think of anything I've done that would cause this.

    But looks like I shouldn't be using that anyway since the documentation says "You should avoid using this as it produces memory garbage. Use GetContacts instead."

    So my question is, how can I write the above code with GetContacts instead?
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    You should always have contact points returned in that array. The comment is correct though, when you call that property, it creates a new array and populates it with contacts. When you've finished with it then it is left to the GC as waste. This is even worse if you iterate the property using an index as each access creates a new array. For ANYTHING that returns an array, don't index into it but first assign it to another variable then index that.

    It should be obvious how to use Collision2D.GetContacts but as the doco states, provide an array of a useful size and pass it in. It'll populate the array and return how many contacts were returned. The purpose here being that you control the created array and can reuse it again and again without causing GC waste.

    Can you please create a simple reproduction case and send me the case number so I can take a look at it immediately?

    Thanks.
     
  3. eighto

    eighto

    Joined:
    Apr 27, 2013
    Posts:
    32
    Well I think I've figured out both issues. The empty array was due to having two different scripts call OnCollisionEnter on the same game object, with the first script deactivating the game object in OnCollisionEnter. I don't know why this wasn't happening before though.

    And GetContacts wasn't working because my array only had a size of 1. When I increased the size it worked. I'm only interested in the first contact point so I originally thought 1 would be enough. I still don't know how this all works.

    Thanks for your help.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    If you're only interested in the first contact point then you should be able to pass an array with only 1 element. It'll essentially fill up the array then stop so you can dictate the maximum number of contacts by the size of the array.
     
  5. eighto

    eighto

    Joined:
    Apr 27, 2013
    Posts:
    32
    Hm well I put it back down to 1 and now it's working. Don't know what I did. Oh well, it's all working now.
     
    MelvMay likes this.
  6. helios

    helios

    Joined:
    Oct 5, 2009
    Posts:
    308
    I can confirm that the same thing happens to me - contacts array is always empty after updating to 2017.2. Can also confirm that GetContacts with a size of 1 did not work, but a size of 2 did (only interested in the first contact point).
     
  7. bob5438

    bob5438

    Joined:
    Nov 10, 2017
    Posts:
    1
    Just wanted to +1 that Collision2D.GetContacts is behaving erratically for me with arrays of length one. I get a return value of 0, and the point (0,0) returned 75% of the time -- it matched up on 2/8 collisions. index 0 for Arrays of length two seem to match up with the contacts [0] values.

    Code (CSharp):
    1.  
    2. private void OnCollisionEnter2D(Collision2D aCol)
    3.     {
    4.      
    5.         print("pointsColliding: " + aCol.contacts.Length);
    6.         print("First point that collided, contacts[0]: " + aCol.contacts[0].point);
    7.  
    8.         ContactPoint2D[] fContacts = new ContactPoint2D[1];
    9.         int Array1Length = aCol.GetContacts(fContacts);
    10.         print("GetContacts Size 1: " + fContacts[0].point + "Array Length: " + Array1Length);
    11.     }
    Output is:
    pointsColliding: 9
    First point that collided, contacts[0]: (-4.0, 0.5)
    GetContacts Size 1: (0.0, 0.0)Array Length: 0

    Note -- origin is pretty far away from anything that's actually going on here.

    Using 2017.2.0f3. Collision is between a polygoncollider2D and a tilemapcollider2D. Haven't filed any bug reports before so I'll look into a more formal report before I go to work. Just wanted to post here since a couple other folks flagged it.
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    As I said above.
     
  9. Gizhaie

    Gizhaie

    Joined:
    Sep 18, 2013
    Posts:
    1
    I encountered this issue as well the other day. I made a bug report and sent you the case number @MelvMay. It would be great if you could have a look at it!
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    Thanks. Note that I received another bug reported for the same thing not long ago. I can confirm it’s a bug and will get fixed ASAP.
     
    haddaDpk and Gizhaie like this.
  11. helios

    helios

    Joined:
    Oct 5, 2009
    Posts:
    308
    This still happens to me in 2018.1b13. Has this been resolved?
     
    haddaDpk likes this.
  12. Cloud_H

    Cloud_H

    Joined:
    Aug 7, 2019
    Posts:
    1
    • I met the same problem:GetContacts always return 0, contactPoint2D[0] = (0,0).I don't know how to solve it
     
    haddaDpk likes this.
  13. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    I don't know how to solve it either, please provide more info or upload a reproduction project so I can have a look.

    In the end, if it's returning no contacts then I would ask if you've checked if there are actually contacts. You can see live contacts in the inspector on any Rigidbody2D/Collider2D in the "Info > Contacts" rollout. Pause your project and take a look.

    Also, it's easy to assume "you've got the same problems" but a lot of the time it's not.