My double jump script is not working

Hi my script isn’t working but I cant figure out why. I can’t jump in midair which is what I’m going for. I want to be able to jump twice, once from the ground and once in midair. Think Ghouls & Ghosts or Smash Bros. The logic doesn’t seem flawed anyway hope some of you can help.

var speed : float = 6.0;

var jump : float = 10.0;

var dJump : float = 7.0;

var gravity : float = 20.0;

private var canDJump : boolean = false;

private var isJumping : boolean = false;

private var isDJumping : boolean = false;

private var velocity : Vector3 = Vector3.zero;

function Update()
{

var controller : CharacterController = GetComponent(CharacterController);

if (controller.isGrounded)

{
	velocity = Vector3 (Input.GetAxisRaw ("Horizontal"), 0, 0);
	velocity = transform.TransformDirection (velocity);
	velocity *= speed;
	isDJumping = false;
		
	if (Input.GetButtonDown ("Jump"))
		{
			velocity.y = jump;
			isJumping = true;
			
		}
}

if (isJumping == true)
{
	canDJump = true;
}

if (canDJump == true && Input.GetButtonDown ("Jump"))
{
	velocity.y = dJump;
	isDJumping = true;
}
if (isDJumping == true)
{
	canDJump = false;
	isJumping = false;
}
		

velocity.y -= gravity * Time.deltaTime;
controller.Move (velocity * Time.deltaTime);

}

The problem is likely that you check the Jump button again immediately after jumping. Since its still the same frame as before, since its the same method, the jump button is still pressed so you double jump immediately.

Your code needs to make sure this isn’t all happening in the same frame like so:

var jump : float = 10.0;

var dJump : float = 7.0;

var gravity : float = 20.0;

private var canDJump : boolean = false;

// These two variables become unnecessary
//private var isJumping : boolean = false;
//private var isDJumping : boolean = false;

private var velocity : Vector3 = Vector3.zero;

function Update() 
{

	// Note: This should really be done in Start as you don't want to waste time every frame getting the controller
	var controller : CharacterController = GetComponent(CharacterController);
	
	// By moving this above the jump check you can ensure it only happens on frames after the jump was performed
	if (canDJump == true && Input.GetButtonDown ("Jump"))
	{
		velocity.y = dJump;
		//isDJumping = true; // Removed - never used
		canDJump = false; // NEW!
	}
	
	if (controller.isGrounded)
	{
		velocity = Vector3 (Input.GetAxisRaw ("Horizontal"), 0, 0);
		velocity = transform.TransformDirection (velocity);
		velocity *= speed;
		//isDJumping = false; // Removed - never used
	 
		if (Input.GetButtonDown ("Jump"))
		{
			 velocity.y = jump;
			 //isJumping = true; // Removed - never used
			 canDJump = true; // NEW!
		}
	}

	// This block is flawed - you only want to double jump once right?
	// Then just set canDJump once the second you start jumping
	/*if (isJumping == true)
	{
		canDJump = true;
	}*/
	
	// This block is flawed - just set CanDJump = false the second you start DJumping
	/*if (isDJumping == true)
	{
		canDJump = false;
		isJumping = false;
	}*/
	 
	velocity.y -= gravity * Time.deltaTime;
	controller.Move (velocity * Time.deltaTime);
}