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);
}
}