0
\$\begingroup\$

I followed a tutorial about implementing a wall jump but one thing that doesn't work is getting the character pushed on the opposite side of the wall when pressing the jump button. As it is, character is only jumping on the y axis upwards on the wall. I read a possible solution that my move code in the FixedUpdate is overriding my wall jumping code. I tried to set a condition to run the move code only if isWallJumping bool is false but to no avail. I have no idea what to try next.

Here is my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class PlayerController : MonoBehaviour {

public Animator animator;

public Rigidbody2D rb;
public float speed;
private float moveInput;
public float jumpForce;
public float maxFallVelocity = -20;

private bool isGrounded;
public Transform feetPos;
public float checkRadius;
public LayerMask whatIsGround;

private float jumpTimeCounter;
public float jumpTime;
private bool isJumping;

IEnumerator dashCoroutine;
bool isDashing;
bool canDash = true;
float normalGravity;

bool isTouchingFront;
public Transform frontCheck;
bool wallSliding;
public float wallSlidingSpeed;
public bool wallJumping;
public float xWallForce;
public float yWallForce;
public float wallJumpTime;

private bool facingRight = true;

void Start()
{
    rb = GetComponent<Rigidbody2D>();
    normalGravity = rb.gravityScale;
}

void Update()
{
    Debug.Log("The velocity in the Y-axis is: " + rb.velocity.y);

        isGrounded = Physics2D.OverlapCircle(feetPos.position, .2f, whatIsGround);

        //Flipping

        if (moveInput > 0 && facingRight == false)
        {
            Flipper();
        }
        else if (moveInput < 0 && facingRight == true)
        {
            Flipper();
        }

        //////////////////////////////////////////////////////////
        //Animation
        /////////////////////////////////////////////////////////
        if (Input.GetButtonDown("Jump") && rb.velocity.y == 0)
            rb.AddForce(Vector2.up * 700f);

        if (Mathf.Abs(moveInput) > 0 && rb.velocity.y == 0)
            animator.SetBool("Running", true);
        else
            animator.SetBool("Running", false);

        if (rb.velocity.y == 0)
        {
            animator.SetBool("Jumping", false);
            animator.SetBool("Falling", false);
        }

        if (rb.velocity.y > 0.2)
        {
            animator.SetBool("Jumping", true);
        }

        if (rb.velocity.y < 0)
        {
            animator.SetBool("Jumping", false);
            animator.SetBool("Falling", true);
        }

        if (isDashing && moveInput > 0)
        {
            animator.SetBool("Dashing", true);
        }
        else if (isDashing && moveInput < 0)
        {
            animator.SetBool("Dashing", true);
        }
        else
        {
            animator.SetBool("Dashing", false);
        }
        ///////////////////////////////////////////////////////
        // Jumping
        //////////////////////////////////////////////////////

        if (isGrounded == true && Input.GetButtonDown("Jump"))
        {
            isJumping = true;

            jumpTimeCounter = jumpTime;
            rb.velocity = Vector2.up * jumpForce;
        }
        if (Input.GetButton("Jump") && isJumping == true)
        {
            if (jumpTimeCounter > 0)
            {
                rb.velocity = Vector2.up * jumpForce;
                jumpTimeCounter -= Time.deltaTime;
            }
            else
            {
                isJumping = false;
            }
        }

        if (Input.GetButtonUp("Jump") && rb.velocity.y > 0)
        {
            isJumping = false;
            rb.velocity = new Vector2(rb.velocity.x, 0f);

        }


        /////////////////////////////////////////////////////////
        // DASHING
        if (Input.GetButtonDown("Dash") && canDash == true)
        {
            if (dashCoroutine != null)
            {
                StopCoroutine(dashCoroutine);
            }
            dashCoroutine = Dash(.4f, .5f);
            StartCoroutine(dashCoroutine);
        }

        ////////////////////////////////////////////////////////
        // Wall Jumping

        isTouchingFront = Physics2D.OverlapCircle(frontCheck.position, .2f, whatIsGround);

        if (isTouchingFront == true && isGrounded == false && moveInput != 0)
        {
            wallSliding = true;
        }
        else
        {
            wallSliding = false;
        }
        if (wallSliding)
        {
            rb.velocity = new Vector2(rb.velocity.x, Mathf.Clamp(rb.velocity.y, -wallSlidingSpeed, float.MaxValue));
        }

        if (Input.GetButtonDown("Jump") && wallSliding == true)
        {
            wallJumping = true;
            Invoke("SetWallJumpingToFalse", wallJumpTime);
        }

        if (wallJumping == true)
        {
            rb.velocity = new Vector2(xWallForce * -moveInput, yWallForce);
        }        
}


private void FixedUpdate()
{
        if (wallJumping != true)
    { 
        moveInput = Input.GetAxisRaw("Horizontal");
        rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
    }
    ///////////////////////////////////////////////////////////////////////
    ///DASHING
    //////////////////////////////////////////////////////////////////////
    if (isDashing && moveInput > 0)
    {
        rb.AddForce(new Vector2(1f * 130, 0), ForceMode2D.Impulse);
    }
    if (isDashing && moveInput < 0)
    {
        rb.AddForce(new Vector2(1f * -130, 0), ForceMode2D.Impulse);
    }

}
//DASHING SCIENCE FICTION 
IEnumerator Dash(float dashDuration, float dashCooldown)
{
    Vector2 originalVelocity = rb.velocity;
    isDashing = true;
    canDash = false;
    rb.gravityScale = 0;
    rb.velocity = new Vector2(originalVelocity.x, 0);
    yield return new WaitForSeconds(dashDuration);
    isDashing = false;
    rb.gravityScale = normalGravity;
    rb.velocity = new Vector2(originalVelocity.x, 0);
    yield return new WaitForSeconds(dashCooldown);
    canDash = true;
}


void Flipper()
{
    transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
    facingRight = !facingRight;
}

void SetWallJumpingToFalse()
{
    wallJumping = false;
}

}

\$\endgroup\$
1
  • \$\begingroup\$ Please trim excessive whitespace (multiple blank lines in a row) from your code before sharing it; excessive whitespace makes the code much harder to read \$\endgroup\$
    – Kevin
    Feb 26 at 21:28
0
\$\begingroup\$

You should use Debug.Log() to better understand what your code is doing:

//...
    if (Input.GetButtonDown("Jump") && wallSliding == true)
    {
        Debug.Log("Started wall jumping. Will stop in " + wallJumpTime);
        wallJumping = true;
        Invoke("SetWallJumpingToFalse", wallJumpTime);
    }
//...

void SetWallJumpingToFalse()
{
    Debug.Log("Setting wallJumping to false");
    wallJumping = false;
}

My first guess would be that you forgot to set a value for wallJumpTime in the Inspector. Since you didn't specify a default value in your code, the value will be 0 if you don't set it in the Inspector.


A few other issues with your code:

  • Always specify default values for primitive numbers (ints, floats) so the code will still work even if you forget to set something in the Inspector
  • Never use Invoke(); it refers to functions by name using a string, which is bad for many reasons (IDE doesn't detect the reference, code will break if you rename function, etc). Use coroutines instead.
  • Never put public variables into your scripts. Use [SerializeField] private or [SerializeField] protected if you want it to show in the Inspector
  • if (wallJumping != true) can be shortened to if (!wallJumping)
  • Your Update() function is way too long. The engine doesn't care, but it's messy and makes the code harder to read. Since that function is already divided into sections, you should split the sections off into their own functions, e.g.
void Update() {
    isGrounded = Physics2D.OverlapCircle(feetPos.position, .2f, whatIsGround);
    CheckFlipping();
    Animate();
    CheckJumping();
    CheckDashing();
    CheckWallJumping();
}

\$\endgroup\$
4
  • \$\begingroup\$ Thank you Kevin for pointing out the many issues with my code. I am following many different youtube tutorials and trying many different things but it's time to start thinking about clean code practices. Regarding the WallJumpTime, it is in the inspector and I (sort of) solved it but not the way I wanted. I basically made it so I don't have to give Input while wallClinging. Though it is not what I wanted. \$\endgroup\$
    – Bluebear
    Feb 26 at 22:34
  • \$\begingroup\$ @Bluebear Did you try adding logging as I suggested, so you can better understand what your code is doing? \$\endgroup\$
    – Kevin
    Feb 26 at 23:28
  • \$\begingroup\$ I added the Debug.Log but don't see anything in the debug console. I also changed (most) of my public floats to [SerializeField] thanks for that. The problem I have now is, I don't know how to flip the character as he is wallJumping. As well as adding a way to control the intensity of the wallJump i,e short bursts to climb vertically or a long button press to jump on the opposite side, but that is a separate question i think. Thanks \$\endgroup\$
    – Bluebear
    Feb 28 at 1:57
  • \$\begingroup\$ If you don't see anything in the debug console, that means the code isn't running, which should help you diagnose and solve the issue. \$\endgroup\$
    – Kevin
    Mar 1 at 19:51
0
\$\begingroup\$

The character can jump now without using horizontal move input, since i removed the move input requirement in order to wall jump. line 161:

if (isTouchingFront == true && isGrounded == false && moveInput != 0)

to

if (isTouchingFront == true && isGrounded == false)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.