- Home /
How do you make a 2D character jump at a fixed height no matter how much you press jump?
Currently if I quickly tap the jump button my character will only jump slightly off the floor and if I hold it for a bit long will reach a max height. If I want to make the character only jump to one height regardless of how I press the jump button what in my code would I have to modify?
Current player controller code:
public class PlayerController : MonoBehaviour {
public float maxSpeed = 5.0f;
public float jumpHeight = 1.0f;
public float checkRadius = 0.2f;
public Transform groundChecker;
public LayerMask whatIsGround;
private bool performJump = false;
private bool grounded;
private bool facingRight = true;
private Animator animationController;
// Use this for initialization
void Start () {
animationController = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
//Checks whether the player wants to jump
if (Input.GetAxis("Jump") > 0 && grounded){
performJump = true;
}
}
void FixedUpdate () {
//Gets user input for moving along the horizontal axis
float move = Input.GetAxis ("Horizontal");
//Checks whether the player is on the ground
grounded = Physics2D.OverlapCircle (groundChecker.position, checkRadius, whatIsGround);
if (!grounded) {
animationController.SetBool ("Grounded",false);
}
else{
animationController.SetBool ("Grounded",true);
}
animationController.SetFloat ("Speed", Mathf.Abs(move));
rigidbody2D.velocity = new Vector2 (maxSpeed * move, rigidbody2D.velocity.y);
//Flips direction if moving in opposite direction to where character is facing
if (facingRight && move < 0) {
flipCharacter();
}
else if (!facingRight && move > 0){
flipCharacter();
}
//Jumps if the jump boolean has been set to true
if (performJump) {
jump ();
performJump = false;
}
}
void flipCharacter(){
//Flips the character based on local scale
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x = theScale.x * -1;
transform.localScale = theScale;
}
void jump(){
rigidbody2D.AddForce (Vector2.up * jumpHeight,ForceMode2D.Impulse);
}
}
Probably something with your "grounded" variable is wrong? Because he should jump only when grounded and can not do it in mid-air.
Answer by hardband · Feb 11, 2015 at 04:05 AM
I found out how to fix it, it was because I was using Input.GetAxis, rather than Input.GetButtonDown, so the force was applied multiple times.
But it was applied only on frames when your character is grounded, so it will not cause it to jump in mid-air.
Furthermore, your character jump is unaffected by jump axis, so that should not affect height. Are you sure your ground check works right?
Well in a sense it was a problem with grounded, the problem was that for some amount of frames after the character jumped he was still technically grounded, meaning if the space bar was held extra force would be added every frame it was grounded (as axis checks if the button is down each frame, whereas GetButtonDown only becomes true for the frame it is pressed). There current implementation of grounded makes it difficult to get frame perfect precision on whether the character is grounded, but GetButtonDown should mostly fix that, although obviously with the caveat if you could enter inputs fast enough it would apply the extra force.
Well, those lines work a bit different, I just want to make sure you understand that.
void Update () {
//Checks whether the player wants to jump
if (Input.GetAxis("Jump") > 0 && grounded){
performJump = true;
}
}
Each frame you are checking if button is pressed and setting bool performJump to true if it was.
void FixedUpdate () {
if (performJump) {
jump ();
performJump = false;
}
void jump(){
rigidbody2D.AddForce (Vector2.up * jumpHeight,Force$$anonymous$$ode2D.Impulse);
}
}
Fixed update works a bit different in comparison to regular Update, running in fixed periods of time, and that is how physics works: it is frame-independent. You can see it if you run something with physical simulation, even a simple falling rigidbody can show you that, and setting Time.timeScale to samething like 0.25 or less: the framerate will be normal, but physics will be notably step-like, the rigidbody will now fall not smooth, but with discreet steps. With normal time scale (which is 1) you just can't notice that.
So your script applies force in fixed update, which is the right way, making applied force framerate-independent. It's no matter how many frames the space was pressed, but it is matter how many physical steps it was pressed AND your character was considered grounded.
Yeah I did know the difference between update and fixed update, the language I used in my previous comment was incorrect and should have talked about the fixed update intervals rather than frames, but the concept as to why this fixed it is still more or less the same. Thanks for offering the advice and such though.
Your answer
Follow this Question
Related Questions
[Unity 4.3] 2D physics - SpeedUp Platform/Slope [C#] 0 Answers
How to check if an object hits the ground hard enough then add explosive force around it (2D) 1 Answer
How would you make a pulling/sucking/attracting mechanic? 2 Answers
Mario Styled Jumping 1 Answer
Jumping from special jump orb 1 Answer