Search Unity

Physics2D Circlecast Hit result is not on collider

Discussion in 'Physics' started by sharkwithlasers, Feb 7, 2021.

  1. sharkwithlasers

    sharkwithlasers

    Joined:
    Dec 8, 2012
    Posts:
    23
    Hi there! I've encountered an unexpected result when using Physics2D.CircleCast. It collides at a location 0.0025 units extended from the collider:

    upload_2021-2-7_1-34-36.png

    upload_2021-2-7_1-34-52.png

    (In this case, I'm casting from the circle to the gray wall on the right. The green dot is the hit point of a Physics2D.Raycast...and the red dot is the hit point of a Physics2D.Circlecast). The gray is the Boxcollider, and the red line is something I drew in OnDrawGizmos.

    I'm using Unity 2019.4.11f1 on Windows. Is this behavior to be expected?

    (more info...the circle cast radius is 0.115, and the left side of the wall is positioned at x = 5)

    EDIT: Updated to Unity 2019.4.19f1 and the issue persists.
     
    Last edited: Feb 7, 2021
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,456
    Physics isn't about giving you exact geometry intersections, you'll need to use your own library for that; it's about where it would consider a contact. In most cases offsets for polygons uses the DefaultContactOffset. Note that the above is 2.5mm and should be considered trivial.
     
  3. sharkwithlasers

    sharkwithlasers

    Joined:
    Dec 8, 2012
    Posts:
    23
    Thanks!

    I was unaware of Contact Offsets, and that 2.5mm lines up with the results that I see. Is there a reason this ContactOffset is only used for CircleCasts, and not RayCasts?

    For some of my games, (e.g. a 2D Platformer), I've forgone using RigidBodies for movement (I do use Kinematic RigidBodies to get Trigger Messages however), but I've used Collider2D's and Raycasts for collision detection (kinda like in this video:
    )

    Should I not utilize Colliders / Raycasts at all in this case? I'm assuming that exact geometry intersection isn't necessary here. I just need to make sure that my character doesn't move into colliders.
     
    Last edited: Feb 7, 2021
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,456
    It's not that CircleCasts do use it but more that Raycasts don't. All shape casts and collider overlaps use the same physics code (Box2D) that's used to calculate contacts during the physics simulation step. Raycasts and OverlapPoint are not used by the physics system and are pure utility intersection queries against colliders and as such don't incorporate that into them.

    As an aside, the physics system only uses conatct offset on intersections with polygons which is why in Box2D it's known as b2_polygonRadius; circle/circle don't use it.

    All I can say is that raycast not taking default contact offset into account is the least of your issues if you're using raycast to detect collisions because after all, it's a swept point and unelss your collider(s) are points it'll never be accurate which is why there's swept collider/rigidbody support i.e. Cast. There's also Rigidbody2D.Distance and Collider2D.Distance which help determining overlap or separation and ways to solve it to move into contact without overlap or out of overlap (iteratively) etc.

    You could also take a look at my GitHub repo, specifically this scene which shows you Kinematic movement combining swept colliders and Distance calls to move/slide around. That can be seen here:
     
    Last edited: Feb 8, 2021
    sharkwithlasers likes this.
  5. sharkwithlasers

    sharkwithlasers

    Joined:
    Dec 8, 2012
    Posts:
    23
    Wow, thanks! That top-down example was extremely helpful! It's working really well for my current use case: (circle that follows the mouse cursor / touch position).

    This is getting a bit off the original topic, but I did notice that making small movements with the mouse cursor results in jerky movement of the player. I believe this is because of the:

    if (m_Movement.sqrMagnitude <= Epsilon)
    return;


    check. But from what I can tell, the Epsilon check helps ensure that the player doesn't get stuck in a collider. I'm curious if there's a way to have smooth smaller movements, while still ensuring the player doesn't get stuck.


    I'm not really familiar with this terminology (e.g. swept point, swept collider), so it's a bit hard for me to wrap my head around. Are there any resources you could point me to to get a better grasp of this? Should I go through the Box2D documentation?
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,456
    I'd not seen that before so I just spun-up the project and yes I could reproduce it. It was a simple fix though which I pushed to master here as well as a minor change similar to what you suggested here. Just pull those changes. The issue was that it was overshooting the target continually so the move needs to be limited to the actual target position otherwise overshoot means it's oscillating through the target position when the target is less than the move-speed/time. Thanks for the report.

    Well it's breaking down the words Ray & Cast. Cast (or sweep) means project or move something through a space. When you do a Circle Cast it's a cast (sweep) of a circle through space. A ray therefore is a point cast through space.

    You can get a ray to hit an obstacle where a circle wouldn't. Using a ray to detect where a character would hit might be easy but it's not accurately representing where a circle would hit as the circle has an area.
     
    Last edited: Feb 8, 2021
    sharkwithlasers likes this.
  7. sharkwithlasers

    sharkwithlasers

    Joined:
    Dec 8, 2012
    Posts:
    23
    Works like a charm! Thanks!

    And I think I understand what you are saying now. Using a single raycast (aka sweeping a single point) to do collision detection for a character is not wise, that makes sense to me.
     
    MelvMay likes this.
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,456
    Well it works and can be adequate but it's not an accurate representation of whether your non-ray-shaped character will hit at that point so it's a compromise if that makes sense.