Search Unity

Unity 2D - Help with Wall Jumping

Discussion in '2D' started by ArtNinJackson, Feb 17, 2020.

  1. ArtNinJackson

    ArtNinJackson

    Joined:
    May 20, 2014
    Posts:
    7
    Howdy!

    So I'm not sure how prevalent this problem is, or if anyone is having a similar problem, but I noticed the other day that my wall jumping script isn't working as well as I'd hoped. I was able to look up some tutorials for the first part, but I've been trying to fine-tune how it feels to wall jump over the weekend and found no success.

    Just the long and short of the problem, my character jumps and slides slowly down any object tagged with "wall." This works as intended. He can even jump from the wall, which works as intended. However, he jumps very "weakly." I'm not really sure how to describe it any way.

    When on the ground, my character's jump has a very distinct arc, but when hopping from a wall, it feels like I barely pressed the button.

    I'll include my script below. Any help is appreciated!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerPlatformerController : PhysicsObject
    6. {
    7.     private RaycastHit2D leftHit;
    8.     private RaycastHit2D rightHit; //Raycasts detect if you're touching an object to the left or right.
    9.     public bool touchingWall; //a bool to determine if you're touching a wall.
    10.     float rightPositionX;
    11.     float leftPositionX;
    12.  
    13.     public float maxSpeed = 10;
    14.     public float jumpTakeOffSpeed = 20;
    15.     public float fallMultiplier = 2.5f; //from tutorial; jumping feels wonky because gravity isn't speeding up fall.
    16.     public float lowJumpMultiplier = 2f; //for when you don't jump all the way
    17.  
    18.     BoxCollider2D playerBoxCollider;
    19.     ParticleSystem particles;
    20.     Rigidbody2D rb;
    21.     ParticleSystem ps;
    22.     private SpriteRenderer spriteRenderer;
    23.     private Animator animator;
    24.  
    25.     // Use this for initialization
    26.     void Awake()
    27.     {
    28.         playerBoxCollider = GameObject.Find("PlayerObject").GetComponent<BoxCollider2D>();
    29.         particles = GameObject.Find("PlayerParticles").GetComponent<ParticleSystem>();
    30.         spriteRenderer = GetComponent<SpriteRenderer>();
    31.         animator = GetComponent<Animator>();
    32.         rb = GetComponent<Rigidbody2D>();
    33.         rightPositionX = playerBoxCollider.bounds.max.x + .1f;
    34.         leftPositionX = playerBoxCollider.bounds.min.x - .1f;
    35.  
    36.     }
    37.  
    38.     private void Update()
    39.     {
    40.         ComputeVelocity();
    41.  
    42.         leftHit = Physics2D.Raycast(new Vector2(leftPositionX + transform.position.x, this.transform.position.y), new Vector2(leftPositionX - 0.2f, 0.0f), 0.2f);
    43.         rightHit = Physics2D.Raycast(new Vector2(rightPositionX + transform.position.x, this.transform.position.y), new Vector2(rightPositionX + 0.2f, 0.0f), 0.2f); //determines if the raycast is connnecting with a wall
    44.  
    45.         if (leftHit.collider != null)
    46.         {
    47.             if (leftHit.collider.tag == "wall")
    48.             {
    49.                 Debug.Log("You're touching a wall."); //testing the functionality with debugs
    50.                 touchingWall = true;
    51.             }
    52.         }
    53.  
    54.         if (rightHit.collider != null)
    55.         {
    56.             if (rightHit.collider.tag == "wall")
    57.             {
    58.                 Debug.Log("You're touching a wall.");
    59.                 touchingWall = true;
    60.             }
    61.         }
    62.  
    63.         if (rightHit.collider == null && leftHit.collider == null)
    64.         {
    65.             touchingWall = false;
    66.             Debug.Log("You're no longer touching a wall.");
    67.         }
    68.  
    69.     }
    70.  
    71.     protected override void ComputeVelocity()
    72.     {
    73.         Vector2 move = Vector2.zero;
    74.         move.x = Input.GetAxis("Horizontal");
    75.  
    76.         if (Input.GetButtonDown("Jump") && grounded)
    77.         {
    78.             velocity.y = jumpTakeOffSpeed + 3f;
    79.         }
    80.         else if (Input.GetButtonUp("Jump"))
    81.         {
    82.             if (rb.velocity.y < 0)
    83.             {
    84.                 rb.velocity += Vector2.up * Physics2D.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
    85.             }
    86.             if (velocity.y > 0)
    87.             {
    88.                 velocity.y = velocity.y * 0.5f;
    89.                 rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
    90.             }
    91.         }
    92.  
    93.         if(Input.GetButtonDown("Jump") && !grounded && touchingWall)
    94.         {
    95.             velocity.y = jumpTakeOffSpeed + 3f;
    96.         }
    97.  
    98.         bool flipSprite = (spriteRenderer.flipX ? (move.x > 0.0f) : (move.x < 0.0f));
    99.         if (flipSprite)
    100.         {
    101.             spriteRenderer.flipX = !spriteRenderer.flipX;
    102.             maxSpeed = 10;
    103.         }
    104.  
    105.         animator.SetBool("grounded", grounded);
    106.         animator.SetBool("crouchEngaged", crouchEngaged);
    107.         animator.SetFloat("velocityX", Mathf.Abs (velocity.x) / maxSpeed);
    108.  
    109.         targetVelocity = move * maxSpeed;
    110.        
    111.         if ((move.x != 0.0f) && !grounded) //if set as (move.x > 0) it works only running left, but not right
    112.         {
    113.            particles.Play(true);
    114.         }
    115.        
    116.         else if (velocity.x == 0.0f)
    117.         {
    118.            particles.Play(false);
    119.         }
    120.  
    121.         if (Input.GetKey(KeyCode.LeftControl))
    122.         {
    123.             playerBoxCollider.enabled = false;
    124.             maxSpeed = 4;
    125.             crouchEngaged = true;
    126.  
    127.         }
    128.         else if (Input.GetKeyUp(KeyCode.LeftControl))
    129.         {
    130.             crouchEngaged = false;
    131.             playerBoxCollider.enabled = true;
    132.             maxSpeed = 10;
    133.  
    134.         }
    135.  
    136.         if (Input.GetKey(KeyCode.LeftShift))
    137.         {
    138.            if(maxSpeed < 20) {
    139.                 maxSpeed += 3 * Time.deltaTime;
    140.             }
    141.  
    142.         }
    143.  
    144.         if (Input.GetKeyUp(KeyCode.LeftShift))
    145.         {
    146.             maxSpeed = 10;
    147.         }
    148.        
    149.     }
    150.     // research needs to be done on this function.
    151.    /*bool Stand()
    152.     {
    153.         //work in progress
    154.        
    155.     }*/
    156. }
     
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Hi @ArtNinJackson

    I checked your code very quickly, I didn't see you add any force when you are jumping away from wall.

    Why not add both horizontal and vertical velocity when you press jump while touching wall and not ground?
     
  3. ArtNinJackson

    ArtNinJackson

    Joined:
    May 20, 2014
    Posts:
    7
    That's a very good point. I hadn't given it much thought. I think the problem is that the acceleration due to gravity is still happening when I'm "in the air," i.e., touching the wall, jumping or falling. After playing some Mario, I think I've concluded that the fall of gravity is reset after each jump from a wall, and the entire falling is slowed as a result of touching a wall (basically gravity is effecting your character still, just about half as fast when you're touching a wall). I'm going to try to add some more force, but the problem is (I still fear) that every time I jump, the force of gravity is as strong as the leap upward, so it's more of a stalemate jump at best.

    Let me try your suggestion and I'll post here again should something be resolved. @eses
     
  4. ArtNinJackson

    ArtNinJackson

    Joined:
    May 20, 2014
    Posts:
    7
    @eses I've done what you've suggested, but it didn't seem to solve the problem. I think I need to decrease the fall speed when touching a wall, and reset the velocity caused by gravity after every jump. I'm just not sure how to make that happen.
     
  5. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @ArtNinJackson

    I would reset the gravity every frame character is in contact either with walls or with floor.