How do I stop infinite jumping in air?
Hello, I’m extremely new to Unity and coding as a whole, as I’m having some problems here (using C#). Whenever I jump, this is a 2D sidescroller, it works well and exactly how I want it to. However, if I continue to press the spacebar, then the character continues to jump in air. This creates a flying effect that I don’t want, how do I fix this? Please answer in detail, as I know next to nothing about coding. Heres my script for the player.
public class Player : MonoBehaviour {
public float maxSpeed = 3;
public float speed = 50f;
public float jumpPower = 150f;
public float jumpSpeed = 8f;
private Rigidbody2D rigidBody;
public bool canJump;
public bool grounded;
private Rigidbody2D rb2d;
private Animator anim;
void Start ()
{
rb2d = gameObject.GetComponent<Rigidbody2D> ();
anim = gameObject.GetComponent<Animator> ();
}
void Update ()
{
{
anim.SetBool ("Grounded", grounded);
anim.SetFloat ("Speed", Mathf.Abs (Input.GetAxis ("Horizontal")));
if (Input.GetAxis ("Horizontal") < -0.1f)
transform.localScale = new Vector3 (-1, 1, 1);
if (Input.GetAxis ("Horizontal") > 0.1f)
transform.localScale = new Vector3 (1, 1, 1);
if (Input.GetKeyDown (KeyCode.Space) && grounded) {
rb2d.AddForce (new Vector2 (0, jumpPower));
}
}
}
void FixedUpdate ()
{
{
float h = Input.GetAxis ("Horizontal");
//Moving the player
rb2d.AddForce ((Vector2.right * speed) * h);
//Limiting the speed of player
if (rb2d.velocity.x > maxSpeed) {
rb2d.velocity = new Vector2 (maxSpeed, rb2d.velocity.y);
}
if (rb2d.velocity.x < -maxSpeed) {
rb2d.velocity = new Vector2 (-maxSpeed, rb2d.velocity.y);
}
}
}
}
Don’t think it has anything to do with First Person Shooters, but the script is fine, you just had the Input.GetKey checking the value of ‘canjump’ instead of checking the value of ‘grounded’ which is the variable(parameter) you were using in the Animator.
So just use if (Input.GetKeyDown (KeyCode.Space) && grounded)
instead.
**One thing to note: ‘canjump’ is actually unnecessary since ‘grounded’ can do all the work. It is a good example of efficient programming logic though. For example, if the player is GROUNDED, then they CANJUMP. If the player is not GROUNDED, then they can’t JUMP. Basically it’s a redundant variable. In your case, the same checking can be done with ‘If the PLAYER is GROUNDED, then he can jump’. Although if later you add flying states, climbing states, etc, then you might need variables like ‘canjump’ because if you were climbing up a ladder, for example, you would NOT be ‘grounded’ but you still could jump(‘canjump’) off the ladder, or up it.
Anyways, here’s the corrected script, tested with added DebugLog’s:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour {
public float maxSpeed = 3;
public float speed = 50f;
public float jumpPower = 150f;
public float jumpSpeed = 8f;
private Rigidbody2D rigidBody;
public bool canjump;
public bool grounded;
private Rigidbody2D rb2d;
private Animator anim;
void Start ()
{
rb2d = gameObject.GetComponent<Rigidbody2D> ();
anim = gameObject.GetComponent<Animator> ();
}
void Update ()
{
{
anim.SetBool ("Grounded", grounded);
anim.SetFloat ("Speed", Mathf.Abs (Input.GetAxis ("Horizontal")));
if (Input.GetAxis ("Horizontal") < -0.1f)
transform.localScale = new Vector3 (-1, 1, 1);
if (Input.GetAxis ("Horizontal") > 0.1f)
transform.localScale = new Vector3 (1, 1, 1);
if (Input.GetKeyDown (KeyCode.Space) && grounded) {
rb2d.AddForce (new Vector2 (0, jumpPower));
Debug.Log("JUMP" + " - Ground:" + grounded + " CanJump:" + canjump + " ");
}
}
}
void OnCollisionEnter2D(Collision2D Other){
if (Other.collider.gameObject.tag == "floor") {
grounded = true;
canjump = true;
Debug.Log("COLL-Enter" + " - Ground:" + grounded + " CanJmp:" + canjump + " ");
}
}
void OnCollisionExit2D(Collision2D Other){
if (Other.collider.gameObject.tag == "floor") {
grounded = false;
canjump = false;
Debug.Log("COLL-Exit" + " - Ground:" + grounded + " CanJmp:" + canjump + " ");
}
}
void FixedUpdate ()
{
{
float h = Input.GetAxis ("Horizontal");
//Moving the player
rb2d.AddForce ((Vector2.right * speed) * h);
//Limiting the speed of player
if (rb2d.velocity.x > maxSpeed) {
rb2d.velocity = new Vector2 (maxSpeed, rb2d.velocity.y);
}
if (rb2d.velocity.x < -maxSpeed) {
rb2d.velocity = new Vector2 (-maxSpeed, rb2d.velocity.y);
}
}
}
}
Check unity’s default FPS controller, it has a script and the componentes for it. The bunch of checks you have to make in order to know if you can jump are kinda complex to explain (and write in here), specially if you want something neat. Unity has a default one.
Tag your floor object “floor” and put the following code.
public bool canjump ;// Add this variable to your code
void Update () {
if(Input.GetKey(KeyCode.Space)&&canjump){
//Jump code
}
}
void OnCollisionEnter2D(Collision2D Other){
if (Other.collider.gameObject.tag == "floor") {
canjump = true;
}
}
void OnCollisionExit2D(Collision2D Other){
if(Other.collider.gameObject.tag == "floor"){
canjump = false;
}
}
}