- Home /
Why is my 2d jumping script weird?
I've written the following code to make a ridigbody2D character jump:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerJump : MonoBehaviour
{
Rigidbody2D rb2d;
private float jumpHeight = 10;
public const string UP = "up";
string jumpState;
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.Space))
{
jumpState = UP;
}
else
{
jumpState = null;
}
}
private void FixedUpdate()
{
if (jumpState == UP)
{
rb2d.AddForce(new Vector2(0, jumpHeight), ForceMode2D.Impulse);
}
}
}
Now, it kind of works? Like, the character jumps when I press space but only sometimes. Also, if I move in air the character does a weird Mary Poppins glide and loses a lot of vertical speed. What's gone wrong?
Answer by Llama_w_2Ls · Jan 20, 2021 at 06:47 PM
Firstly, Update() and FixedUpdate() run on their own timeloops, which means that Update could be called several times before FixedUpdate is called. This means, if you tap space (not hold), there is a slight delay before it actually jumps, which is enough time for the update to run again and set jumpState to null, since space isn't being held anymore. Preferably, you should put everything related to jumping in the same method. Either in FixedUpdate or just Update. Not both please.
Secondly, I see no ground checking there, so your player is able to jump whilst still in the air. This might create some weird gliding issue, as force is still being added, reducing the vertical velocity downward. @tokeleth_unity
Thanks, I know that it's missing a ground check but I wanted to make sure the basic function actually worked first. I'll try putting them in the same update, and writing a ground check.
Okay so, the problem persists even when everything in Update is moved to FixedUpdate
Is the string JumpState needed in order to manage jumping? There should be no logic issues if you just write:
void FixedUpdate()
{
if (Input.GetKey(KeyCode.Space))
{
rb2d.AddForce(new Vector2(0, jumpHeight), Force$$anonymous$$ode2D.Impulse);
}
}
Probably not honestly, it's a holdover from an earlier version, let me try that out
Preferably, you should put everything related to jumping in the same method. Either in FixedUpdate or just Update. Not both please.
Wrong. Input detection should be done in Update, and applying force in FixedUpdate.
void Update()
{
if (Input.GetKey(KeyCode.Space))
{
jumpState = UP;
}
}
private void FixedUpdate()
{
if (jumpState == UP)
{
rb2d.AddForce(new Vector2(0, jumpHeight), Force$$anonymous$$ode2D.Impulse);
jumpState = null;
}
}
Your answer
