Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug Wall jump not working correctly

Discussion in 'Scripting' started by Penguwastaken, Sep 30, 2023.

  1. Penguwastaken

    Penguwastaken

    Joined:
    May 1, 2022
    Posts:
    43
    Hey! so, I am trying to make the player able to wall jump in unity 2D.


    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Player : MonoBehaviour
    4. {
    5.     [Header("Jump")]
    6.  
    7.     public float moveSpeed = 5f;
    8.     public float jumpForce = 10f;
    9.     public Transform groundCheck;
    10.     public LayerMask groundLayer;
    11.  
    12.     [Header("stuff")]
    13.     public Rigidbody2D rb;
    14.     private bool isGrounded;
    15.     private float groundCheckRadius = 0.1f;
    16.     public Transform holder;
    17.     private int lastInput;
    18.     private Animator anim;
    19.  
    20.     public bool HasKey;
    21.     public GameObject key;
    22.  
    23.     public ParticleSystem blood;
    24.  
    25.     private bool canMove;
    26.     private Vector2 moveVelocity;
    27.     private float moveInput;
    28.  
    29.     [Header("Wall Jump")]
    30.     public Transform wallCheck;
    31.     public bool InWall;
    32.     public bool IsSliding;
    33.     public float slidingSpeed;
    34.  
    35.     public bool wallJumped;
    36.     public float moveCooldown;
    37.  
    38.     public Vector2 wallJumpForce;
    39.  
    40.     private float h;
    41.  
    42.     private void Awake()
    43.     {
    44.         canMove = true;
    45.         rb = GetComponent<Rigidbody2D>();
    46.         anim = GetComponent<Animator>();
    47.     }
    48.  
    49.     private void Update()
    50.     {
    51.         Debug.Log(rb.velocity);
    52.  
    53.         // Check if the player is grounded.
    54.         isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
    55.  
    56.         // Handle player input for movement.
    57.         if (canMove)
    58.         {
    59.             if (!wallJumped)
    60.             {
    61.                 moveInput = Input.GetAxis("Horizontal");
    62.             }
    63.             else if (wallJumped)
    64.             {
    65.                 moveInput = Input.GetAxis("Horizontal");
    66.                 if (moveInput >= 0.3f)
    67.                     moveInput = 1;
    68.                 else if(moveInput <= -0.3f)
    69.                     moveInput = -1;
    70.             }
    71.  
    72.             moveVelocity = new Vector2(moveInput * moveSpeed, rb.velocity.y);
    73.         }
    74.         else
    75.         {
    76.             moveInput = 0;
    77.         }
    78.  
    79.         if (wallJumped && canMove)
    80.         {
    81.             if (moveInput != 0)
    82.                 rb.velocity = moveVelocity;
    83.             else if (moveInput == 0)
    84.                 rb.velocity = rb.velocity;
    85.         }
    86.         else if(canMove && !wallJumped)
    87.         {
    88.             rb.velocity = moveVelocity;
    89.         }
    90.  
    91.         h = moveInput;
    92.  
    93.         // Handle jumping ==========================================================================
    94.  
    95.         if (isGrounded && Input.GetButtonDown("Jump"))
    96.         {
    97.             rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
    98.         }
    99.  
    100.         if (!isGrounded && IsSliding && Input.GetButtonDown("Jump") && InWall)
    101.         {
    102.             if (wallCheck.position.x < transform.position.x)
    103.                 rb.velocity = new Vector2(wallJumpForce.x, wallJumpForce.y);
    104.             else if (wallCheck.position.x > transform.position.x)
    105.                 rb.velocity = new Vector2(wallJumpForce.x * -1, wallJumpForce.y);
    106.  
    107.             canMove = false;
    108.             wallJumped = true;
    109.             IsSliding = false;
    110.             InWall = false;
    111.             Invoke("canMoveNow", moveCooldown);
    112.         }
    113.  
    114.         // OTHER STUFF ============================================================================
    115.         if (canMove)
    116.         {
    117.             if (moveInput >= 0.1f)
    118.                 transform.localScale = new Vector3(-1, 1);
    119.             else if (moveInput <= -0.1f)
    120.                 transform.localScale = new Vector3(1, 1);
    121.         }
    122.  
    123.         InWall = Physics2D.OverlapCircle(wallCheck.position, groundCheckRadius, groundLayer);
    124.  
    125.         if (InWall && !isGrounded)
    126.         {
    127.             IsSliding = true;
    128.         }
    129.         else
    130.             IsSliding = false;
    131.  
    132.  
    133.  
    134.         if (wallJumped && isGrounded)
    135.         {
    136.             canMove = true;
    137.             wallJumped = false;
    138.             rb.velocity = Vector3.zero;
    139.         }
    140.         else if (isGrounded)
    141.         {
    142.             wallJumped = false;
    143.         }
    144.  
    145.         // TURN AFTER WALLJUMP ========================================================================================
    146.  
    147.         if (rb.velocity.x >= 0.1f && wallJumped)
    148.             transform.localScale = new Vector3(-1, 1);
    149.         else if (rb.velocity.x <= -0.1f && wallJumped)
    150.             transform.localScale = new Vector3(1, 1);
    151.  
    152.         if (InWall && !isGrounded)
    153.             GetComponent<SpriteRenderer>().flipX = true;
    154.         else if (InWall && isGrounded || !InWall && isGrounded || !InWall && !isGrounded)
    155.             GetComponent<SpriteRenderer>().flipX = false;
    156.  
    157.  
    158.         // ANIMS =======================================================================================================
    159.  
    160.         if (Mathf.Abs(moveInput) > 0)
    161.         {
    162.             anim.SetBool("Running", true);
    163.         }
    164.         else
    165.             anim.SetBool("Running", false);
    166.     }
    167.  
    168.     private void FixedUpdate()
    169.     {
    170.         if (IsSliding)
    171.         {
    172.             rb.velocity = new Vector2(rb.velocity.x, Mathf.Clamp(rb.velocity.y, -slidingSpeed, float.MaxValue));
    173.         }
    174.     }
    175.  
    176.     public void Die()
    177.     {
    178.         blood.transform.parent = null;
    179.         blood.Play();
    180.         Destroy(gameObject);
    181.     }
    182.  
    183.     private void canMoveNow()
    184.     {
    185.         canMove = true;
    186.     }
    187.  
    188.  
    189. }
    it works fine, but something's not working right. when the canMoveNow function is executed, the player turns around mid-air. I believe it happens because the player is somehow keeping some of the speed he had when he first touched the wall.

    https://cdn.discordapp.com/attachme...292a49b33d9d7f59735a99f5bc0b468b662a908ef6d3&
     
  2. Calumniator

    Calumniator

    Joined:
    Jul 5, 2023
    Posts:
    24
    That sounds like your collision detection is still set to Discrete. Go to your player's Rigidbody2D and set the Collision Detection to Continuous. Most likely that will do the trick.
     
  3. Penguwastaken

    Penguwastaken

    Joined:
    May 1, 2022
    Posts:
    43
    I believe collision detection mode is already set to continuous but I can't check it right now. I don't understand how would that solve my problem tho.
    I've probably explained it badly. So basically, when the player wall jumps and the canMoveNow function is executed, the player turns around and start going to the wrong side. For some reason it starts going towards the wall with the speed that he had when he touched the wall.
     
  4. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    541
    Yikes! That's a lot of code! :)

    You can let Unity do the wall sliding by adding a slippery physics material to your character. A friction value of 0.05 should do it.

    The only thing you need to do is choose a jump direction based on what is near your character.

    Something like this:

    Code (CSharp):
    1.     void Update()
    2.     {
    3.         rb.drag=2f;
    4.         if (Input.GetButtonDown("Jump"))
    5.         {
    6.             Vector2 jumpDirection=Vector2.zero;
    7.             if (Physics2D.OverlapCircle(transform.position+Vector3.right*0.6f,0.5f,groundLayer))   // wall to the right?
    8.                 jumpDirection=new Vector2(-20,20);
    9.             else if (Physics2D.OverlapCircle(transform.position+Vector3.left*0.6f,0.5f,groundLayer)) // wall to the left?
    10.                 jumpDirection=new Vector2(20,20);
    11.             if (Physics2D.OverlapCircle(transform.position+Vector3.down*0.6f,0.5f,groundLayer))    // ground below?
    12.                 jumpDirection=Vector2.up*20;
    13.             rb.AddForce(jumpDirection, ForceMode2D.Impulse);
    14.         }
    15.         rb.velocity+=new Vector2(Input.GetAxis("Horizontal"),0);
    16.         transform.localScale=new Vector3(Mathf.Sign(-rb.velocity.x),1);
    17.     }
    18.  
     
  5. Penguwastaken

    Penguwastaken

    Joined:
    May 1, 2022
    Posts:
    43
    It seems like that will work, I will try it later. Just one doubt: wouldn't making the Player's physic material slippery make the ground also slippery for the player? I prefer keeping the sliding system I made to avoid future problems, just in case. Anyway, thanks!
     
  6. Chubzdoomer

    Chubzdoomer

    Joined:
    Sep 27, 2014
    Posts:
    106
    It would, but you could always just have your "ground check" swap out your character's slippery physics material for the non-slippery one.
     
  7. Penguwastaken

    Penguwastaken

    Joined:
    May 1, 2022
    Posts:
    43
    It works, but it is very weird.I changed some stuff to make it fit my preferences. Basically is like if the player kind of teleported towards the direction. I believe its not teleporting, but going too fast instead.The wallJumpForce is set 20, 20. I basically want to make the wall jumping similar to super meat boy's wall jump. I probably did something wrong. Here's the current Update method:

    Code (CSharp):
    1. private void Update()
    2.     {
    3.         // Check if the player is grounded.
    4.         isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
    5.         if (canMove)
    6.         {
    7.             moveInput = Input.GetAxis("Horizontal");
    8.             moveVelocity = new Vector2(moveInput * moveSpeed, rb.velocity.y);
    9.             rb.velocity = moveVelocity;
    10.         }
    11.         else
    12.         {
    13.             moveInput = 0;
    14.         }
    15.         // Handle jumping ==========================================================================
    16.         if (Input.GetButtonDown("Jump"))
    17.         {
    18.             Vector2 jumpDirection = Vector2.zero;
    19.             if (wallCheck.position.x < transform.position.x && InWall && !isGrounded) // wall to the right?
    20.             {
    21.                 jumpDirection = new Vector2(wallJumpForce.x * 1, wallJumpForce.y);
    22.             }
    23.             else if (wallCheck.position.x > transform.position.x && InWall && !isGrounded)  // wall to the left?
    24.             {
    25.                 jumpDirection = new Vector2(wallJumpForce.x * -1, wallJumpForce.y);
    26.             }
    27.             if (isGrounded) // ground below?
    28.             {
    29.                 jumpDirection = Vector2.up * jumpForce;
    30.             }
    31.             rb.AddForce(jumpDirection, ForceMode2D.Impulse);
    32.         }
    33.         // OTHER STUFF ============================================================================
    34.         if (canMove)
    35.         {
    36.             if (moveInput >= 0.1f)
    37.                 transform.localScale = new Vector3(-1, 1);
    38.             else if (moveInput <= -0.1f)
    39.                 transform.localScale = new Vector3(1, 1);
    40.         }
    41.         InWall = Physics2D.OverlapCircle(wallCheck.position, groundCheckRadius, groundLayer);
    42.         if (InWall && !isGrounded)
    43.         {
    44.             IsSliding = true;
    45.         }
    46.         else
    47.             IsSliding = false;
    48.         if (wallJumped && isGrounded)
    49.         {
    50.             canMove = true;
    51.             wallJumped = false;
    52.             rb.velocity = Vector3.zero;
    53.         }
    54.         else if (isGrounded)
    55.         {
    56.             wallJumped = false;
    57.         }
    58.         // TURN AFTER WALLJUMP ========================================================================================
    59.         if (rb.velocity.x >= 0.1f && wallJumped)
    60.             transform.localScale = new Vector3(-1, 1);
    61.         else if (rb.velocity.x <= -0.1f && wallJumped)
    62.             transform.localScale = new Vector3(1, 1);
    63.         if (InWall && !isGrounded)
    64.             GetComponent<SpriteRenderer>().flipX = false;
    65.         else if (InWall && isGrounded || !InWall && isGrounded || !InWall && !isGrounded)
    66.             GetComponent<SpriteRenderer>().flipX = true;
    67.         // ANIMS =======================================================================================================
    68.         if (Mathf.Abs(moveInput) > 0)
    69.         {
    70.             anim.SetBool("Running", true);
    71.         }
    72.         else
    73.             anim.SetBool("Running", false);
    74.     }
     
  8. Penguwastaken

    Penguwastaken

    Joined:
    May 1, 2022
    Posts:
    43
    I still didn't fix it, please help me :(
     
  9. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    541
    If 20 is too fast then try 5. :)