How can I make my character double Jump? (C#)

I have been trying to get my character to double jump, but it never works, if anyone can help, that would be amazing.

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

public class PlayerMovement : MonoBehaviour
{
    public CharacterController controller;

    public float speed = 12f;
    public float gravity = -9.81f;
    public float jumpHeight = 3f;

    public Transform groundCheck;
    public float groundDistance = 0.4f;
    public LayerMask groundMask;


    Vector3 velocity;
    bool isGrounded;

    // Update is called once per frame
    void Update()
    {
        isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);

        if(isGrounded && velocity.y < 0)
        {
            velocity.y = -2f;
        }

        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        Vector3 move = transform.right * x + transform.forward * z;

        controller.Move(move * speed * Time.deltaTime);

        if(Input.GetButtonDown("Jump") && isGrounded)
        {
            velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
        }

        velocity.y += gravity * Time.deltaTime;

        controller.Move(velocity * Time.deltaTime);
    }
}

It won’t jump again because you’re checking if player isGrounded. While player is in the air, he’s not grounded, so even if you press space you won’t be able to jump again. Change

if(Input.GetButtonDown("Jump") && isGrounded)

to

if(Input.GetButtonDown("Jump"))

and it will probably let you jump indefinitely as many times as you want. Change your code accordingly to your preferences.

I tried your script and it seems like you’re not checking if the “jump” button is pressed while in the air. The easiest way to fix this would be to add the line

if (Input.GetButton(“Jump”))
moveDirection.y = jumpSpeed;

to the else statement in your update function.

I would also recomend you to use Input.GetButtonDown insted of Input.GetButton.

Input.GetButton will trigger as long as you hold the “Jump” button down, making the player fly to infinity if you hold the button long enough.

Input.GetButtonDown on the other hand will only trigger once each time you press the “Jump” button, making the player jump accordingly to your jumpSpeed variable.

And if you only need double jumping and not “infinity jumping” you need some sort of counter to keep track on how many times you’ve double jumped.

A good coding custom is to avoid repetitions in the code. The movement in your if and else statements seems to be doing the same thing. So it’s only needed once, outside of the if/else statement.

I’d say you should make 1 more bool variable (midAirJump) and rewrite your if block to something like that:

if(Input.GetButtonDown("Jump"))
{
    if (isGrounded)
    {
        velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);    //your jumping code
        midAirJump = true;
    }
    else if (midAirJump)
    {
        velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);    //your jumping code
        midAirJump = false;
    }
}

That’s not exactly code, but I think it should work.

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

public class playerMove : MonoBehaviour
{
//Variables
public CharacterController characterController;
public float speed = 12f;
Vector3 velocity;
public float gravityForce = -9.81f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundLayer;
public float jumpHeight;
bool isGrounded;
bool doubleJump = false;
public float doubleJumpHeight = 0f;
bool canJump = false;

void Start() {

}

void Update() {
    isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundLayer);

    if(isGrounded && velocity.y < 0) {
        velocity.y = -2f;
    }

    if(isGrounded) {
        doubleJump = true;
        canJump = true;
    }

    float x = Input.GetAxis("Horizontal"); //Get x axis
    float z = Input.GetAxis("Vertical"); //Get z axis

    Vector3 move = transform.right * x + transform.forward * z;
    characterController.Move(move * speed * Time.deltaTime);

    if(canJump == true) {
        if(Input.GetButtonDown("Jump")) {
            velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravityForce);
            canJump = false;
        if(Input.GetButtonDown("Jump") && doubleJump == true) {
            velocity.y = Mathf.Sqrt(doubleJumpHeight * -2f * gravityForce);
            doubleJump = false;
        }
        }
    }

    velocity.y += gravityForce * Time.deltaTime;
    characterController.Move(velocity * Time.deltaTime);
}

}

This is my double jump v of code