Player double jumping instead of jumping just once

I’ve been making a game based off the Roll a Ball Tutorial to learn unity and scripting. I’ve added jumping to the game using a bool isGrounded to check whether or not the player is in contact with the ground or not, it all seems to work except if I double tap the spacebar key fast enough he double jumps instead of just jumping once.

Here are the parts of my script for the player object:

public float speed;
private Rigidbody rb;
public float jumpheight;
public bool isGrounded;

void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

void OnCollisionStay()
	{
		isGrounded = true;
	}

void FixedUpdate ()
	{
		if (Input.GetKeyDown ("space") && isGrounded)
		{
			
			Vector3 jump = new Vector3 (0.0f, jumpheight, 0.0f);
			GetComponent<Rigidbody> ().AddForce (jump);
			isGrounded = false;
		}
		float moveHorizontal = Input.GetAxis ("Horizontal");
		float moveVertical = Input.GetAxis ("Vertical");

		Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);

        rb.AddForce (movement * speed);
	}

try like this:

 public float speed;
 private Rigidbody rb;
 public float jumpheight;
 public bool isGrounded;
 int pad;
 void Start()
     {
         rb = GetComponent<Rigidbody>();
     }
 
 void OnCollisionStay()
     {
         isGrounded = true;
     }
 
 void FixedUpdate ()
     {if(pad>0){pad--;  isGrounded = false;}
         if (Input.GetKeyDown ("space") && isGrounded)
         {if(pad==0){
             pad=3;//<adjust this number
             Vector3 jump = new Vector3 (0.0f, jumpheight, 0.0f);
             GetComponent<Rigidbody> ().AddForce (jump);
             isGrounded = false;
         }}
         float moveHorizontal = Input.GetAxis ("Horizontal");
         float moveVertical = Input.GetAxis ("Vertical");
 
         Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
 
         rb.AddForce (movement * speed);
     }

I think that the way that you’ve coded it, the variable ‘isGrounded’ will become true when the player hits the ground, but nothing in your script sets it to false again when the player jumps.
OnCollisionStay() is called on the frame that the player hits the ground and every frame after
OnCollisionEnter() is called only on the frame that the player hits the ground
OnCollisionExit() is called on the frame that the player leaves the ground

so instead of:

void OnCollisionStay()
     {
         isGrounded = true;
     }

try:

void OnCollisionEnter()
{
    isGrounded = true;
}

void OnCollisionExit()
{
    isGrounded = false;
}

I think this will work, but i could be wrong. Let me know :slight_smile: