Having some trouble making a wall jump

I’m a beginner at unity and I was having some trouble trying to code in a wall jumping mechanic, I wanted the mechanic to work as such:

  • The code checks for if you are touching the wall and not touching the floor, once this is done flipping left or right should be locked until no longer in contact with the wall, if you are touching the wall and there is no input then you should slowly start sliding down the wall.

  • If you are on the wall and you press space, it will launch you up and away from the wall for about 0.2s, if you press space and up you will jump up the wall.

The way I want it to work is similar to how it works in games like Hollow Knight, I’m also having a glitch where my character will only slide down the wall when facing it.

I’ll post my current code at the time of writing this, some help on how to fix it would be appreciated.

public class PlayerMovement : MonoBehaviour
{
    public float speed;
    public float jumpForce;
    private Rigidbody2D body;
    private Animator anim;
    private int Right;
    private BoxCollider2D boxCollider;
    [SerializeField] private LayerMask groundLayer;
    [SerializeField] private LayerMask wallLayer;
    private float WallJumpCooldown;
    private float horizontalInput;
    public float WallJumpTime;
    private float WallJumpCounter;

    //from GunMove
    public GameObject Player;
    private bool facingRight = true;
    private bool WallJump;

    private void Awake()
    {
        boxCollider = GetComponent<BoxCollider2D>();
        body = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        Right = -1;
    }

    private void Update()
    {
      
        if (Input.GetKey(KeyCode.W))
            WallJumping();
        //Invoke("WallJumping", 2.0f);

        Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        //this code changes the velocity
        horizontalInput = Input.GetAxis("Horizontal");
        //changes direction based on mouse
  
    if(WallJumpCounter <= 0)
    {
        if (mousePos.x < transform.position.x && facingRight)
        {
            flip();
        }
        else if (mousePos.x > transform.position.x && !facingRight)
        {
            flip();
        }

        anim.SetBool("Run", horizontalInput != 0);
        anim.SetBool("Grounded", IsGrounded());
        anim.SetBool("OnWall", TouchWall());

        void flip()
        {
            facingRight = !facingRight;
            transform.localScale = new Vector3(1 * Right, 1, 1);
            Right = Right * -1;
        }

        //wall jumping
        if (WallJumpCooldown > 0.2f)
        {
            body.velocity = new Vector2(horizontalInput * speed, body.velocity.y);

            if (TouchWall() && !IsGrounded())
            {
                body.gravityScale = 4.9f;
                body.velocity = Vector2.zero;
                Debug.Log("onWall");
            }
            else if (!TouchWall())
            {
                body.gravityScale = 5;
                Debug.Log("offWall");

            }

        }
        else
            WallJumpCooldown += Time.deltaTime;

        if (Input.GetKey(KeyCode.Space))
            Jump();
    }
    else
        {
            WallJumpCounter -= Time.deltaTime;
        }
}

    private void Jump()
    {
        if(IsGrounded())
        {
            body.velocity = new Vector2(body.velocity.x, jumpForce);
            anim.SetTrigger("Jump");
        }
        else if(TouchWall() && !IsGrounded())
        {
          
            if (!Input.GetKey(KeyCode.Space))
            {
              
                //lock flipping
            }
            else if (Input.GetKey(KeyCode.Space) && TouchWall() && !IsGrounded())
            {
                WallJumpCounter = WallJumpTime;
                body.velocity = new Vector2(-Input.GetAxisRaw("Horizontal") * speed * 1.4f, jumpForce);
                //body.gravityScale = 5;
            }

        }
    }

    private bool IsGrounded()
    {
        RaycastHit2D raycastHit = Physics2D.BoxCast(boxCollider.bounds.center, boxCollider.bounds.size, 0, Vector2.down, 0.1f, groundLayer);
        return raycastHit.collider != null;
    }

    private bool TouchWall()
    {
        RaycastHit2D raycastHit = Physics2D.BoxCast(boxCollider.bounds.center, boxCollider.bounds.size, 0, new Vector2(-Right , 0), 0.3f, wallLayer);
        return raycastHit.collider != null;
    }

    void WallJumping()
    {
        body.velocity = new Vector2(-body.velocity.x, body.velocity.y);
    }

}

When posting code to the forum, make sure you use Code Tags so people can read it easier.

alr, srry. this should be easier to read

Some pretty redundant code in here. Does it print out anything if you Debug.Log inside of the Jump method in the walljump section?

Another thing I noticed is that you never reset WallJumpCooldown anywhere, and I don’t even know why you have it in the first place.

Sorry I’m pretty much a complete beginner and would like to improve, how do you think I should clear up my code?
Also I jus removed the debugs because they were just put there to test if the code actually worked and also the WallJumpCooldown since it didn’t really have a purpose.

Not really related to your problem, but I’ll just mention this one thing I noted. A lot of other stuff is probably just personal preference on how to organize your own stuff, if you understand what’s happening there’s not really a problem, it’ll just be worse if other people read your code. There are some tips and tricks you can pick up about writing clean and maintainable code that can make returning to old code a lot easier. The redundant thing I was talking about was mostly in your Jump method, as you do a bunch of BoxCasts even though you already know the results.

        if(IsGrounded())
        {
            body.velocity = new Vector2(body.velocity.x, jumpForce);
            anim.SetTrigger("Jump");
        }
        else if(TouchWall() && !IsGrounded()) // <== don't need to check isGrounded again since if you're here you know it's already false
        {
       
            if (!Input.GetKey(KeyCode.Space)) // <== this is never true since you check if Space is pressed before you call Jump
            {
           
                //lock flipping
            }
            else if (Input.GetKey(KeyCode.Space) && TouchWall() && !IsGrounded()) // <== same thing, don't need to check any of these
            {
                WallJumpCounter = WallJumpTime;
                body.velocity = new Vector2(-Input.GetAxisRaw("Horizontal") * speed * 1.4f, jumpForce);
                //body.gravityScale = 5;
            }
        }

Here’s what it looks like after I took out all the redundant checks, it might tell you what you’re possibly missiong.

    private void Jump()
    {
        if (IsGrounded()) // jump from the ground
        {
            body.velocity = new Vector2(body.velocity.x, jumpForce);
            anim.SetTrigger("Jump");
        }
        else if (TouchWall()) // on the wall
        {
            WallJumpCounter = WallJumpTime;
            body.velocity = new Vector2(-Input.GetAxisRaw("Horizontal") * speed * 1.4f, jumpForce);
        }
    }

Back to the actual problem, I asked about the Debugs because I was wondering what parts of the code it actually reaches. It would also help me help you if you could answer these questions:

What does your code do that you don’t want it to do?
What doesn’t it do that you want it to?

From your original post it sounds like only slides down the wall, but I’m not sure if your wall jumping part of it works at all, or if it does nothing.