Search Unity

Box Cast Returning Wrong Normal Vector on diagonal Tiles

Discussion in 'Physics' started by John_Leorid, Jul 2, 2018.

  1. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    650
    A picture says more than thousend words:



    Code (CSharp):
    1.     void Checks() {
    2.         // does not work on diagonal surfaces
    3.         RaycastHit2D groundHit = Physics2D.BoxCast(playerTransform.position, Vector2.one*1.5f, 0, Vector2.down, 1.1f, layerMask);
    4.         grounded = groundHit;
    5.         if (groundHit) {
    6.             groundNormal = groundHit.normal;
    7.             Debug.DrawLine(playerTransform.position, groundHit.point, Color.red);
    8.             Debug.DrawRay(groundHit.point, groundHit.normal, Color.blue);
    9.             Debug.Break();
    10.         }
    11.     }
    Any Idea how to fix this?
     
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,508
    The picture itself doesn't describe the problem. Is it with the collider? With the slope? Is it with the raycast? Or with the character looking like standing on air?

    At first glance, I'd just say that you should use a CapsuleCollider2D instead of a CircleCollider2D for the character.
     
  3. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    650
    Because I uploaded the wrong picture :S

     
  4. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,508
    Most possibly the normal is like that because it's aligned with the box's lower face.

    You're casting a rather large box of 1.5m of semi-axis. The collision point seems to be exactly at 1.5m of in the vertical "down" direction of your character, so we may deduct that the BoxCast method is detecting the collision right at the starting position. It's like if we put a box of 3x3 m enclosing your character. As the direction is down, the normal seems to be based on the lower face of the box.

    I'd bet that the direction of the normal would change if you change the "angle" parameter in the BoxCast (currently 0).

    Without having experience in 2D, I think that any of these solutions would give a better result:
    • Reduce the box size so it doesn't collide with the slope in the starting position. For example, 0.05 * Vector2.one would do. You may need to increase the distance.
    • Use Raycast instead of BoxCast.
     
  5. Vunpac

    Vunpac

    Joined:
    Mar 13, 2012
    Posts:
    34
    I just want to toss one more alternative out there. I use both BoxCast and ray cast for my situation. (it's for something different but I do need to use BoxCast as well as need the proper angles)
    I'll cast a BoxCast in the direction I need then when it hits something I will get the hit point and back up slightly (like 0.1f) then cast a ray from there in the same direction to get the normal it hit.