Here is the code to control my player. On the first jump, it goes really high, jumps after that are normal behaves as I would expect. Every 5 or 6 jumps or so it changes to being high again and then is what I would expect. Any ideas?
void FixedUpdate()
{
if (this.transform.position.y < -10) this.transform.position = new Vector3(0, 2, 0);
if (Input.GetKey(KeyCode.LeftArrow)) this.rigidbody.AddForce(-20, 0, 0, ForceMode.Force);
if (Input.GetKey(KeyCode.RightArrow)) this.rigidbody.AddForce(20, 0, 0, ForceMode.Force);
if (touchingPlatform)
{
if (Input.GetKeyDown(KeyCode.Space))
{
this.rigidbody.AddForce(0, 12, 0, ForceMode.Impulse);
}
}
}
Link to project (it’s literally 1 .cs file and some cubes):
https://www.dropbox.com/s/dlcoxnobztu5og1/JumpinCube.zip?dl=0
You’re not going to have good results calling Input.GetKeyDown inside FixedUpdate. You will miss jumps because Unity’s input system does not update input in FixedUpdate, only Update. This will become very obvious when your frame rate is really high (if you disable VSync for example) because you will have potentially dozens of Update frames for every FixedUpdate that goes by. Your GetButtonDown will show as TRUE in only ONE of these Update frames, so by the time you get to FixedUpdate, it’s false again.
In the case of the super jump, the same thing is happening, only in reverse. GetButtonDown is returning True twice in a row doubling your force. This would mean that FixedUpdate ran twice before Update ran again. You can verify this by adding this line:
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("JUMP "+Time.time);
this.rigidbody.AddForce(0, 12, 0, ForceMode.Impulse);
}
You will see “Jump” in your console twice during the times you get a super jump.
The solution to this is to do your input in Update, not fixed update. Or use an input plugin that can handle getting input in FixedUpdate such as my Rewired input system.
You could also try to filter out the extra jump ignoring the input issue. Your floor detection system using the trigger isn’t preventing your cube from being grounded in the very next frame after you set your force mode, so it’s allowing the extra TRUE returned by GetKeyDown to trigger the jump twice. If you set touchingPlatform = false immediately after the jump it will solve it. OnTriggerExit is not necessarily called immediately when you set the force mode because the cube may not have cleared the -0.01 Y extension distance of the trigger in that one frame of movement.
2 Likes