- Home /
How do I stop jumping in mid air?
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);
}
}
}
}
Answer by Honorsoft · Jan 09, 2018 at 03:08 AM
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);
}
}
}
}
Thank you so much! It's been so frustrating, and it works now! I appreciate this so much haha.
No problem. I checked out the screen shots, looks cool, kinda like paper-$$anonymous$$ario, but with way more color. Scripting can be confusing, I have learned a bunch of program$$anonymous$$g languages and it gets confusing when they're all different and similar also, and I forget which one has what... And Unity's so touchy sometimes, if you change one little thing...the project doesn't work anymore. -lol
PS, Since you're new to coding, I'll give you advice, many wonder which to use, Java or C-Sharp? So I'll offer my opinion on what I've noticed with Unity and how the languages work with it. I prefer C# because it can be more versatile than javascript, but I'm not like others who say pick one or the other, use both. Unity seems to handle compiling both into one build, although in rare circumstances the two could interfere with each other. Java is best for Android app's and most web content, so if you plan online or mobile app's, learn java, but once you learn the basics of C# classes and keep trying out new scripts you find online, I think you'll find C# easier to understand and debug.
Sorry, I forgot to mention, you can add force that will basically add a pre-set(Unity controlled) force, which means it will add a 'burst' of force that won't be affected by the way Update() is called in Unity. Just add an extra 'flag' to your RigidBody line, like this:
rb.AddForce(Vector3.up * JumpVelocity,Force$$anonymous$$ode.Impulse);
Force$$anonymous$$ode.Impulse is not required, but allows you to change what type of physics are applied to the object. Here are the different force modes: Force
- Add a continuous force to the rigidbody, using its mass. Acceleration
- Add a continuous acceleration to the rigidbody, ignoring its mass. Impulse
- Add an instant force impulse to the rigidbody, using its mass. VelocityChange
- Add an instant velocity change to the rigidbody, ignoring its mass.
Answer by black_sheep · Jan 06, 2018 at 10:05 AM
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.
Answer by dapa5678 · Jan 06, 2018 at 06:25 PM
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;
}
}
}
@dapa5678 , this didn't seem to work for me, now my character can't jump. Did I enter the code correctly? I made sure to tag the gameObject as "floor". using System.Collections; using System.Collections.Generic; using UnityEngine;
public class Player : $$anonymous$$onoBehaviour {
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", $$anonymous$$athf.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.Get$$anonymous$$ey ($$anonymous$$eyCode.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;
} }
void FixedUpdate ()
{
{
float h = Input.GetAxis ("Horizontal");
//$$anonymous$$oving 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);
}
}
}
}
change the if statement to
if(Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Space)&&canjump){ and your jump code is not inside your if statement
should be
if (Input.Get$$anonymous$$ey ($$anonymous$$eyCode.Space) && canjump) {
//Jump code
}
}
Not
if (Input.Get$$anonymous$$ey ($$anonymous$$eyCode.Space) && canjump) {
}
//Jump code
}
Also, check that your tag is exactly the same as the one in your code
Thanks $$anonymous$$ :D
Hey, thanks for replying, but the jump still isn't working for some reason. I made sure to tag the gameObject (which is a box collider 2D "floor". Heres my coding again, I probably messed it up again haha. using System.Collections; using System.Collections.Generic; using UnityEngine;
public class Player : $$anonymous$$onoBehaviour {
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", $$anonymous$$athf.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.Get$$anonymous$$ey($$anonymous$$eyCode.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;
} }
void FixedUpdate ()
{
{
float h = Input.GetAxis ("Horizontal");
//$$anonymous$$oving 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);
}
}
}
}