Search Unity

How do I fix my double jump?

Discussion in 'Scripting' started by KingAssassinable, Feb 18, 2018.

  1. KingAssassinable

    KingAssassinable

    Joined:
    Feb 18, 2018
    Posts:
    11
    Hi all. I'm trying to allow for my character to be able to double jump when they have a particular pickup equipped. The pickup all works fine, the problem is the logic for my jump function, which is currently an IEnumerator.
    Code (CSharp):
    1. if (Input.GetAxisRaw("Jump") > 0 & isJumping & doubleJumpEnabled & Time.time >= nextJumpTime)
    2.         {
    3.             if (rb.velocity.y > 5 & !isGrounded)
    4.             {
    5.                 //Debug.Log("Double jump pressed");
    6.                 StartCoroutine(Jump());
    7.                 //doubleJumpEnabled = false;
    8.             }
    9.         }
    10.         else if (Input.GetAxisRaw("Jump") > 0 & !isJumping & Time.time >= nextJumpTime)
    11.         {
    12.             if (isGrounded)
    13.             {
    14.                 //isJumping = true;
    15.                 Debug.Log("Single jump pressed");
    16.                 StartCoroutine(Jump());
    17.             }
    18.         }
    This is the code for where the jump is called, based on it's current state. The top one is for the double jump, the bottom for normal jump.


    Code (CSharp):
    1. IEnumerator Jump()
    2.     {
    3.         if (Input.GetAxisRaw("Jump") > 0 & Time.time >= nextJumpTime & isGrounded & !isJumping)
    4.         {
    5.             float jumpTimeCount = maxJumpTime / Time.deltaTime;
    6.             isJumping = true;
    7.             Debug.Log("Jump!");
    8.             animator.SetTrigger("isJumping");
    9.             for (float i = 1; i <= jumpTimeCount; i++)
    10.             {
    11.                 if (Input.GetAxisRaw("Jump") > 0)
    12.                 {
    13.                     rb.velocity += jumpHeight * (1f/ maxJumpTime) * Time.deltaTime * Vector3.up;
    14.                     Debug.Log("Jump height = " + jumpHeight);
    15.                     yield return new WaitForSeconds(Time.deltaTime);
    16.                 }
    17.                 else
    18.                     break;
    19.             }
    20.             yield return new WaitUntil(() => rb.velocity.y <= 0);
    21.             isFalling = true;
    22.             animator.SetTrigger("isFalling");
    23.             yield return new WaitUntil(() => isGrounded);
    24.             animator.SetTrigger("hasLanded");
    25.             isFalling = false;
    26.             isJumping = false;
    27.             nextJumpTime = Time.time + jumpFreq;
    28.             StopCoroutine(Jump());
    29.         }
    30.         else if (Input.GetAxisRaw("Jump") > 0 & doubleJumpEnabled & Time.time >= nextJumpTime & !isJumping)
    31.         {
    32.             float jumpTimeCount = maxJumpTime / Time.deltaTime;
    33.             isJumping = true;
    34.             Debug.Log("Double Jump!");
    35.             animator.SetTrigger("isJumping");
    36.             for (float i = 1; i <= jumpTimeCount; i++)
    37.             {
    38.                 if (Input.GetAxisRaw("Jump") > 0)
    39.                 {
    40.                     rb.velocity += jumpHeight * (1f / maxJumpTime) * Time.deltaTime * Vector3.up;
    41.                     Debug.Log("Double Jump height = " + jumpHeight);
    42.                     yield return new WaitForSeconds(Time.deltaTime);
    43.                 }
    44.                 else
    45.                     break;
    46.             }
    47.             yield return new WaitUntil(() => rb.velocity.y <= 0);
    48.             isFalling = true;
    49.             animator.SetTrigger("isFalling");
    50.             yield return new WaitUntil(() => isGrounded);
    51.             animator.SetTrigger("hasLanded");
    52.             isFalling = false;
    53.             isJumping = false;
    54.             nextJumpTime = Time.time + jumpFreq;
    55.             StopCoroutine(Jump());
    56.         }
    57.     }
    Here is my main jump function. As you can see, the function works through in steps in order to fit with the player's animations using triggers. For a normal jump, it work fine. However, through countless ways of rearranging things, I cannot get it to work so that once I am in the air and I jump again, it increases the height again. The code either goes into just single jump, or just double jump. I want when I double jump for it to first perform the first jumping code, followed by redoing the jump so the player goes higher. If anybody could help me understand what I'm missing, it'd be much appreciated. I'm just going around in circles here :D
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    One thing I would consider, if I were trying to do this is to remove the extra checks for the axis (and anything else you've just checked before starting the coroutine).

    If you had a bool set 'doubleJump' in the first method area, then perhaps in the jump coroutine you can check for that variable at any valid time and do .. whatever you want to do :)

    I didn't 100% understand how you described it (or might not have, in case I'm wrong), but I think you could probably make your coroutine about 1/2 the size, and if the doubleJump variable is true, you could yield the return of a new jump.
    I did not read every single bit of that, but it looks like it's virtually the same (both parts of the coroutine).
     
  3. ihgyug

    ihgyug

    Joined:
    Aug 5, 2017
    Posts:
    194
    That's a pretty big wall of code for the jump o_o
    But as I see your problem is that you jumping once or twice only...there are tons of ways to achieve a double jump. The first that comes to mind is to have a Max Jump value set to 1, when you collide with something it goes back to the max, when you jump it loses 1. When 0, you can't jump. That should work just fine. When you pick up the power up the Max Jump would be 2...and you can implement even triple jumps, or as many as you want, easily by changing the Max Jump variable.
    Hope it helped!
     
  4. KingAssassinable

    KingAssassinable

    Joined:
    Feb 18, 2018
    Posts:
    11
    Thanks for the response. The reason there are separate checks for the axis in the input area is because one is for when I don't currently have the double jump equipped and the other for when I do. I want to do like you said, and have it check if I have jumped again in the middle. Like I need to be able to detect if I have hit jump again after doing the first jump, before it finishes, so that I can then make it perform the second jump.

    I apologies for my messy code, but this is the way I've had it all figured out and the only real suggestion I need is about adding this second check for a jump into it.
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I'm not disagreeing about the 2 parts of checks for double jump or not double jump. What I meant was there's no need to recheck your input immediately after you begin jumping (and the jump time, etc) since you just check that before calling the function.

    As I was trying to say in my post, if you set a variable under a valid double jump condition in the first part of code (not the coroutine), you should be able to check against this variable in the coroutine at the appropriate time for when a double jump could happen.
     
    KingAssassinable likes this.
  6. KingAssassinable

    KingAssassinable

    Joined:
    Feb 18, 2018
    Posts:
    11
    I see. I'll give that a try. Thank you.
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    you may need to modify your coroutine a bit (besides cutting it in half), so that you can give yourself frames to allow for a IsDoubleJumping variable to be read...
    Also worth mentioning, there's really no need to wait for Time.deltaTime when you could just yield return null, in my opinion that would be simpler and mean more or less the same thing.