Implementing Double Jump into script. Please Help..

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;

public class PlayerController : MonoBehaviour
{

    private Rigidbody2D rb;
    private SpriteRenderer sr;
    private Animator ani;

    public float moveSpeed = 5f;
    public float jumpPower = 8f;
         
    private bool isGrounded;

    public float hangTime  = .1f;
    private float hangCounter;

    public float jumpBufferLength = .1f;
    private float jumpBufferCount;

  
  
  
  
  
  
  
  
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        sr = GetComponent<SpriteRenderer>();
        ani = GetComponent<Animator>();
 
    }

  
    void Update()
    {
        //Horizontal Movement
      
        rb.velocity = new Vector2(Input.GetAxisRaw("Horizontal") * moveSpeed, rb.velocity.y);
        ani.SetFloat("xVelocity", Math.Abs(rb.velocity.x));
        ani.SetFloat("yVelocity", (rb.velocity.y));

        //Sprite Flip

        if (rb.velocity.x > 0)
        {
            sr.flipX = false;
        }
        if (rb.velocity.x < 0)
        {
            sr.flipX = true;
        }

        //Hangtime
        if (isGrounded)
        {
            hangCounter = hangTime;
        }
        else
        {
            hangCounter -= Time.deltaTime;
        }

        //Jump Buffer
        if (Input.GetButtonDown("Jump"))
        {
            jumpBufferCount = jumpBufferLength;

        }
        else
        {
            jumpBufferCount -= Time.deltaTime;
        }


        Jump();

   
    }
    private void Jump()
    {
        if (jumpBufferCount >= 0 && hangCounter > 0f)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpPower);
            jumpBufferCount = 0;

        }


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

        }

        ani.SetBool("isJumping", !isGrounded);
    }
  
  
    //Groundcheck
    private void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            isGrounded = true;                 
        }
    }
    private void OnCollisionExit2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            isGrounded = false;        
          
        }
    }

    private void DoubleJump()
    {
      //This is where im trying to write the double jump ability.
    }
  
 
 




}

Hey, so I have exhausted myself trying to figure this out. I truly didnt want to admit i needed help, but after searching for days and trying many many times through trial and error. I cant get it.

I am trying to, 1. Implement a double jump.
2. Have that double jump be an item, where the method be turned on once the item is obtained.

I have tried every method i could find. Nothing will make this little bugger jump twice.
I don’t need a full solve, but please suggest something, or point me in the right direction.

Why not use a bool to flag when the player can/can’t double jump? If the player isn’t grounded and the flag is true, allow a second jump, then set the flag to false. Then when grounded again, set the flag back to true.

Absolutely, and this was a method i tried, it seems simple enough right.? little guy wont jump. Forget turning the double jump on and off for now, i cant even get him to double jump.!

I would use a scripted state machine to handle motion scenarios like this. Checking bools and velocities to determine state can make things much more complicated down the road.

However… looking at this part of your code:

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

It seems you are taking the existing y-axis velocity and halving it?
Why not try something like this:

            if (Input.GetButtonUp("Jump") && rb.velocity.y > 0)
            {
                rb.velocity += new Vector2 (0.0f, rb.velocity.y * 0.5f);
                // alternately you could do something like this:
                // rb.velocity += new Vector2(0.0f, jumpPower * 0.5f);
            }

You would need to track that the user did the double jump and not invoke that code segment (a bool property for testing purposes would work).

But I think the issue is that you are reducing the velocity on the y-axis and not adding to it?

I believe the whole “halving the velocity” thing is to allow the player to release the jump button to jump less high. That’s pretty common in 2D platformers.

Thank you for the reply, but that code was written for a variable jump height, and not the double jump. If i am however misunderstanding you, would that be creating an issue with implementing the double jump.?
Any code i write, checking for any movement on the y, if hes in mid air, on the ground, and adding while in midair, he can jump agian and then the inmidair would be turned false and bam, double jump. but i cannot get him up there hah.

Do you mind posting the full code (including the collapsed sections in Update()) in a code block? That might help us a bit to understand your game logic.

As a side note, some people on here won’t even consider helping if you’ve only posted screenshots of code… I’d recommend always pasting code into a code block.

Hey i figured out how to actually post the code properly instead of dumping it, do you have any ideas on how i could implement the double jump.?

Looks good, much appreciated!

Could it be jumpBufferCount or hangCounter causing this? It seems those are the only conditions on a new jump happening.

Oh interesting thought actually okay, ill try adding the second jump as a new jump line of code and not the jump method.

Here’s my reference code for coyote timing, multi-jumping and jump buffering:

Full code at:

proximity_buttons is presently hosted at these locations:

https://bitbucket.org/kurtdekker/proximity_buttons

https://github.com/kurtdekker/proximity_buttons

The problem certainly seems to be the hangCounter. This value decreases while you are not on the ground (likely for coyote time) and you don’t allow a jump if the hangCounter has expired. This means that any attempt to jump in the air is going to fail.

Perhaps you could add a bool to track if the doublejump is used and allow a jump even if hangCounter is <= 0.

if (jumpBufferCount >= 0)
{
    if (hangCounter > 0f)
    {
        rb.velocity = new Vector2(rb.velocity.x, jumpPower);
        jumpBufferCount = 0;
    }
    else if(doubleJumpPossible)
    {
        rb.velocity = new Vector2(rb.velocity.x, jumpPower);
        jumpBufferCount = 0;
        doubleJumpPossible = false;
    }
}

You would need to reset doubleJumpPossible back to true when the character is grounded.

2 Likes

Thank you, this worked perfectly. I greatly appreciate the help.