How to only jump when grounded

So i have this basic 2D player code that can jump and move horizontally but the jump can always be initiated, even when already in air. How do i fix this? Code here:

using UnityEngine;
using System.Collections;

public class  Player : MonoBehaviour{

public float moveSpeed = 10f;
	public float jumpSpeed = 10f;

	void Update () {
	float h = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
		if (Input.GetButtonDown ("Jump")){
			rigidbody2D.velocity = new Vector3(0, jumpSpeed, 0);
			}
		transform.Translate (new Vector3 (h, 0));
		
	
	


		}
	}

i would look at the character controller code cuz it has isgrounded() so it can detect that, or maybe google how the character controller does it

My player is a rigidbody as you can see by the rigidbody2D, meaning it doesn't have isgrounded

2 Answers

2

I usually create an enumerator to know the different states of the gameobject. Something like this:

public enum State{
    normal,
    jumping
}
public State state;

And then:

void Update(){
    if (Input.GetButtonDown ("Jump")) Jump();
}

void Jump(){
    //Do whatever you want to jump now
    state = State.jumping;
}

void OnCollisionEnter(Collision collision){
    if (collision.tag == "Ground" && state == State.jumping){
        state = State.normal;
    }
}

This requires you to tag the ground as a “ground”, and of course add a collider to both your player and the ground.

Thank you good sir :)

Actually, there is now another error showing up: Assets/Scripts/C#/Player/Player.cs(30,31): error CS1061: Type UnityEngine.Collision2D' does not contain a definition for tag' and no extension method tag' of type UnityEngine.Collision2D' could be found (are you missing a using directive or an assembly reference?)

if you think this or any other is a good answerto your questiob you should mark it as "answered" so other people can check it as well

i wrote it without unity so i did it wrong... lool for the reference of collicers and try: collision.transform.tag

The only problem with using tags is you have to tag everything you want as grounded and physically enabled objects might be considered grounded sometimes and other times not. This is why the Character Motor uses collision points instead, which is what I tried to convert to rigidbody in my answer.

Alright you will need to use the function OnCollisionStay within your code. Along with contact points (to tell if your characters “feet” are touching the ground). So you will need a boolean within the method:

  void OnCollisionStay(Collision c){

      // Visualize the contact point
	Debug.DrawRay(c.point, c.normal, Color.red);
    //check if the contact point was below an amount of the rigidbodies origin
    if(c.point < 0.5){ //you might use something else here? I would look into it.
    allowJump = true;
    } else{
    allowJump = false;
    }
    }

You would of course need to create the var allowJump as a global variable and then within your if(Input.GetButtonDown(“Jump”)) you would want to have if(Input.GetButtonDown(“Jump”) && allowJump == true)

Note I have not tested this out so it might need a fair amount of tweaking before it works. If you have any questions about it let me know.