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

2D - A small, intermittent problem with CircleCast (), sometimes returns incorrect hit

Discussion in 'Physics' started by NoUJoe, Mar 2, 2016.

  1. NoUJoe

    NoUJoe

    Joined:
    Mar 7, 2014
    Posts:
    30
    circlecastproblem.PNG

    There was a small annoyance in a project I'm working on that I've managed to trace back to this.

    I think sometimes CircleCast returns the wrong hit. In the image you can see that the circle is more embedded in Square (3) than Square (2), yet CircleCast returns Square (2) as the hit, (I dunno about you but I'd have assumed Square (3) to be the hit). So I set up a CircleCastAll to get all the hits and debugged the distances from the cast center point to the hit point, and Square (3) is closer, not I really needed to do that as you can clearly see in the scene that its more embedded in Square (3)!

    Now, most of the time when its embedded more in one collider than another, it does return the more embedded hit, its when the difference in embedded-ness is small that it starts to return the other.

    ALSO ALSO, upon more investigation, it seems that somewhere along the lines its assumed that both hits are equal, so picks the one that is first in the array (all internally, I'm presuming here). This is backed up by moving Square (3), and then moving it back to exactly the same position (i just move it 1 up then 1 down). Now, I've briefly looked through the Box2D source code, before and I know that in some situations, when you resize colliders for example, you have to deattach the old one, and reattach a new, resized one. Unity handles this as part of its implementation so it's all seemless for us. So based on this I can only presume something along the lines of this happens:

    Move collider
    Internal array somewhere gets updated
    Do cast
    Due to the collider being in a different position in the array, the two hits end up being in a different order
    Do "what cast to pick" check
    Returns they are both "the same"
    Pick first in array (which now happens to be Square (3))
    Return Square (3)

    And then if you do the same to Square (2), then it reverses again and now Square (2) gets returned once again!

    So it's a small problem that happens 1% of the time, but it's a little annoying. I can overcome it by using CircleCastAll and looping through, but it would have been nice to not have needed to do that! Anyone have any thoughts, knowledge on this?
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    Your image doesn't really show much detail TBH.

    Due to legacy reasons, RaycastHit(2D) only returns a single point but Box2D can return two. For the casts in Unity, the first hit-point is used and the hit point is a support point not always along an edge.

    Also, when overlapping, the hitPoint isn't necessarily along an edge or on the circumference of the circle. You can see this illustrated nicely here: http://www.iforce2d.net/b2dtut/collision-anatomy.

    The results returned are first sorted by the fraction moved but in the case of overlap, that fraction is zero (do is the RaycastHit2D.distance) so all that is guaranteed is that it will be grouped at the start of the returned results along with other overlapping colliders. The order within the fraction=0 group isn't controlled and will be down to the order returned from the Box2D 'b2World->QueryAABB' call which comes down to the enter of the collider proxy in the Box2D dynamic tree so added order would be part of that.

    Your distance is calculating the start of the cast point to a hitPoint which to Box2D is the point where it would apply force to separate the colliders. This relates not only to the relative positions but in the case of a circle/polygon contact, the angles of the edge and distance to the circle center/radius.