Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

2D Physics - Raycast and Composite Colliders

Discussion in 'Physics' started by TebiFestival, Apr 15, 2020.

  1. TebiFestival

    TebiFestival

    Joined:
    Jul 17, 2015
    Posts:
    3
    Hello everyone!

    So I've been having this problem when using Raycast2D and Composite Colliders. In the image bellow, Green Lines are the ones from a Composite Collider created by having colliders in a Tilemap. Purple Lines are the resulting Normals from a Raycast hitting right at that position, this Raycast stop on hit so they can only detect one hit.

    As you can see on the flat part you get A, and in the part that goes up you get B, both of these are correct since they are normal to the surface. But if a Raycast hits right at the corner, where a line is created due to the composite collider I get the C normal which actually is wrong for the surface, I would expect to have A, or B, or maybe even something in between.

    Also, this composite collider is Polygonal, not outline.

    I'm currently solving this by detecting this odd case and removing it from the rest of hits (basically I replace the C with a B if I detect it), but this requires extra processing and logic since I have different angles and such. I would love to just have the result directly given by the Raycasts.

    Do you have any clues on why is this happening?

    ResultingNormals.png

    Edit: Fixed typo errors.
     
    Last edited: Apr 15, 2020
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,546
    You're not querying against a CompositeCollider2D, you're doing so against the low-level primitives. In this case, you're detecting polygons but if you switch the composite to "Outline" mode it'd be using edges. The physics system only sees circles, capsules, edges & polygons. It'll determine which primitive the ray intersects; it won't take all shapes into consideration as it sees them individually and knows nothing about composites or anything in Unity at all.

    For raycast, Box2D will always return a surface normal (other shape casts may hit the vertex and give you an "interpolated" normal). In-fact, here's the code that does it: b2_polygon_shape::raycast

    The "C" normal you're getting there looks like (due to precision) it's perpendicular to the slope going off the bottom of the image so is a collision normal of that. Whilst that may not be expected, when it comes to intersections exactly where two vertex are, it's almost numerically ambiguous which should be detected. It's likely both are detected however both their distances are identical and because it's from the same collider, you'll only get one. In other areas and depending on the order the polygons are returned from the broadphase, you might've got the result you expected.

    If it were possible for you to use outline mode then you'd only get results from the surface which is where you want it.

    Note, the above would happen if you use a PolygonCollider2D or just did this on BoxCollider2D that were side-by-side although in the multiple BoxCollider2D case, you'd be able to ask for multiple results and determine yourself which you wanted.
     
    TebiFestival likes this.
  3. TebiFestival

    TebiFestival

    Joined:
    Jul 17, 2015
    Posts:
    3
    Hey thanks for the quick answer!

    This is a lot of insight thank you! As you noted there depending on the order the polygons are returned sometimes I DO get the desired result, I did a lot of testing on this prior to this post and the weird effect I show above does happen consistently, but only in specific places of our levels.

    Sadly, due to how we have configured our physic system at the moment it is not possible to change to Outline, however, I will run some tests on Outline just to make sure the behavior does not happen in such a scenario.

    I do remember trying without making it a Composite Collider, or moving the slopes to a different Grid in the Tilemap, but this proven kind of cumbersome and prone to errors for when our level designer got into creating the level.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,546
    While it's more expensive, it might solve your issue if you were to use a CircleCast with a very small radius. I cannot guarantee this but it might be a simpler workaround for you.
     
    TebiFestival likes this.
  5. GamerHangout

    GamerHangout

    Joined:
    Aug 15, 2020
    Posts:
    2
    If anyone is still looking to an easy solution, try setting the "Geometry Type" parameter on the Composite Collider 2D to "Polygons". It worked for me!