- Home /
How do you make a 2D Rigidbody "Jump" Once in Unity?
I'm currently developing a simple 2d game, and of course do to the fact that unity's fricken awesome, I've selected this to make a game rather than just hard coding it or using gamemaker. My character currently can walk right and left, but,
HOW can I make the character jump? All the ways that I've tried make the player just rise continually. People say to create a boolean object like "isGrounded" and it is controlled by "Physics.Raycast" and a long line with transform.position and stuff. The problem was however, that isGrounded won't change.
I'm using Unity 4.6.0f. The character has an animator with an idle animation, a Box Collider 2d, Rigidbody 2D, and PlayerScript.
This is the Code:
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public float speed = 10f;
public Vector2 maxVelocity = new Vector2(3, 5);
public bool standing;
public float jumpHeight = 12f;
public float airSpeedMuiltiplier = 0.3f;
public RaycastHit hit;
public Transform tran;
public bool isGrounded;
void Start () {
tran = transform;
}
void Update () {
var forceX = 0f;
var forceY = 0f;
var absVelX = Mathf.Abs(rigidbody2D.velocity.x);
var absVelY = Mathf.Abs(rigidbody2D.velocity.y);
if(Physics.Raycast (tran.position, -tran.up, 7777f)) {
isGrounded = true;
if(hit.transform.tag == "Terrain") {
isGrounded = true;
} else {
isGrounded = false;
}
} else {
isGrounded = false;
}
if(Input.GetKey ("right") || Input.GetKey (KeyCode.D)) {
if(absVelX < maxVelocity.x) {
forceX = speed;
}
transform.localScale = new Vector3(1, 1, 1);
} else if(Input.GetKey ("left") || Input.GetKey (KeyCode.A)) {
if(absVelX < maxVelocity.x) {
forceX = -speed;
}
transform.localScale = new Vector3(-1, 1, 1);
} else if((Input.GetKeyDown ("up") || Input.GetKey (KeyCode.W)) && isGrounded) {
rigidbody2D.AddForce(new Vector2(0, 54f));
}
rigidbody2D.AddForce(new Vector2(forceX, forceY));
}
}
Thanks in Advance!
>>if((Input.Get$$anonymous$$eyDown ("up") || Input.Get$$anonymous$$ey ($$anonymous$$eyCode.W)) && isGrounded) {
rigidbody2D.AddForce(new Vector2(0, 54f));
}
for consistency, why not make this...
if((Input.Get$$anonymous$$eyDown ("up") || Input.Get$$anonymous$$ey ($$anonymous$$eyCode.W)) && isGrounded) {
forceY = 54f;
}
Still, I would not think it would be a problem to add to forces in a row like that, and AddForce is exactly how I would do it.
isGrounded is only needed if you don't want to be able to jump "again" in the middle of the air. I'd address that AFTER you have the jump movement working as expected.
NOTE: without gravity turned on, adding an upward force WILL make it rise indefinitely. $$anonymous$$ake sure gravity is turned on for the rigid body.
Answer by Pendantic · Mar 10, 2015 at 05:30 AM
First of all this is how I would do the ground check
float isGroundedRayLength =0.1f;
LayerMask layerMaskForGrounded;
public bool isGrounded {
get {
Vector3 position = transform.position;
position.y = GetComponent<Collider2D> ().bounds.min.y + 0.1f;
float length = isGroundedRayLength + 0.1f;
Debug.DrawRay (position, Vector3.down * length);
bool grounded = Physics2D.Raycast (position, Vector3.down, length, layerMaskForGrounded.value);
return grounded;
}
}
This enables checking of the very lowest part of your collider and also has a layer mask which if you make public gives you a drop down list of what physics layers to collide with.
Aswell I would caution restraint on using hard coded values and addforce as they are generally bad practice when making something with the requirement to have precise control over your speed as stopping when using addforce is not simple.
The more common way I've seen it done and also used many times is similar to this
float speed =5f;
void Update(){
rigidbod2D = GetComponent<Rigidbody2D> ();
Vector2 move = rigidbod2D.velocity;
float hor = Input.GetAxis ("Horizontal");
move.x = hor * speed;
if (Input.GetButtonDown ("Jump")&&isGrounded) {
move.y = jumpSpeed;
}
rigidbod2D.velocity = move;
}
this gives a lot more control is very clean and allows for multiple different types of input natively(keyboard(wasd and arrows) and controllers) if that matters to you. Hope this was helpful
Thanks Pendantic! That worked!
I just couldn't find a proper way to check the ground, but now it works!
Thanks for your help
I was stuck on multiple issues involving this for a full day, I was trying my best to use rigidbody to move, but was struggling to get the jump working also. This made perfect sense and is working so smoothly now. Thankyouuu!!!
Yep, this is the best way to do it. I also prefer this approach.
Answer by Stadob · Mar 18, 2018 at 08:02 PM
if(Input.GetButtonDown("Jump") && Mathf.Approximately(rigid.velocity.y,0))
{
rigid.AddForce(new Vector2(0, jumpSpeed) * movementSpeed * Time.deltaTime, ForceMode2D.Impulse);
}
Your answer
Follow this Question
Related Questions
Null values in Unity 1 Answer
How to fix code errors? 1 Answer
How to determine if my plane is facing downards (unityscript) 2 Answers