Is there some way to get two BoxColliders sided normals at the same time? (Is Grounded checking)

I’m using the following code to check ground. But it fail when the character is jumping and fall touching a wall because the code only detect a normal at the same time (i think so).

So i need my variable to be “isGrounded=true” only when boxcollider touch de tilemap on the up side. So, is there some way to solve this problem?

Thank you so much!!

//---------------------------------------------------
    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.CompareTag("Tilemap"))
        {
            state.isGrounded = false;

            if (move == Movement.idle || state.isRuning)
            {
                state.isJumping = false;
                state.isGrounded = true;
                return;
            }

            state.isJumping = true;
        }
    }

    //---------------------------------------------------
    private void OnCollisionEnter2D(Collision2D collision)
    {
        //let jump
        if (move == Movement.up) return;

        int index = 0;
        while (index < collision.contactCount)
        {
            Vector3 normal = collision.GetContact(index).normal;           

            Sides side = new Sides();
            side.AnalizeNormal(normal);
          
            if (side.up)
            {
                state.isJumping = false;
                state.isGrounded = true;
            }

            //Debug.Log(this + " " + side.up + " " + side.right + " " + side.left + " " + side.down);

            index++;
        }
;
    }
        ///----------------------------------------------------
        public void AnalizeNormal(Vector3 normal)
        {
            if (normal.x > 0.1f)
            {
                right = true;
            }
            else if (normal.x < -0.1f)
            {
                left = true;
            }

            if (normal.y > 0.1f)
            {
                up = true;
            }
            else if (normal.y < -0.1f)
            {
                down = true;
            }
        }

Yes, take a look at my Github repo that shows how to use IsTouching (which queries existing contacts) and the ContactFilter2D to filter the query by collision normal angle. The repo is in my signature.

The check for the Rigidbody2D being grounded comes down to a single property like this:
SimpleGroundedController

Here’s the video of that specific example. Link is also in the video description:

The video shows that the character can only jump when grounded. The grounded state is configured to be straight up so the slanted platform or side walls won’t allow the character to jump.

2 Likes

Thank you so much!! :slight_smile:

i succeeded, this was the only way to get it to work properly.
1-Use layer mask
2-Use normal angle
3-min normal angle → 89
4- max normal angle → 91

//---------------------------------------------------
    public ContactFilter2D ContactFilter;
    public bool IsGrounded => rigidBody.IsTouching(ContactFilter);
//---------------------------------------------------

However I had problems using that code in FixedUpdate () as you did in your example. Instead I had to do it like this.

//---------------------------------------------------
    private void OnCollisionExit2D(Collision2D collision)
    {
        state.isGrounded = IsGrounded;
        state.isJumping = !state.isGrounded;
    }
    //---------------------------------------------------
    private void OnCollisionStay2D(Collision2D collision)
    {
        state.isGrounded = IsGrounded;
        state.isJumping = !state.isGrounded;
    }
//---------------------------------------------------

Not sure why you’d have problems apart from the fact that the FixedUpdate is called before any of the 2D/3D physics systems are simulated i.e. create/destroy/update contacts whereas the physics callbacks are called after so you’d be getting the latest data. You can equally call it in “Update” which is always after any previous simulation step.