The height of the jump depends on how long the player presses the jump button. There are only two parameters - height and time. Gravity is constant.
Let's say that the height has three units, and the time is set to a second.
There are fixed time-segments during which velocity must be added. If the player presses the button for the entire second, they will reach the three units height, taking into account the fact that gravity is pulling them down.
When I tried to solve this problem, I was trying to use
v = sqrt(2gH)
formula which was perfect to calculate instant velocity for fixed-height jumps.
Not for this case! My code may look like this:
private float jumpHeight = 3f;
private float jumpTime = 1f;
private const float GRAVITY = -10f;
...
private float timer = jumpTime;
public void FixedUpdate(float fixedDeltaTime) {
if(timer < 0) {
return;
}
timer -= fixedDeltaTime;
var deltaTimeNormalized = fixedDeltaTime / jumpTime;
var deltaHeight = jumpHeight * deltaTimeNormalized;
var jumpVelocityY = CalculateJumpSpeed(deltaHeight, Math.Abs(GRAVITY));
character.rigidbody2D.velocity.y += jumpVelocityY;
}
private float CalculateJumpSpeed(float height, float gravity) {
return Math.Sqrt(2 * height * gravity);
}
The controlled character skyrockets, and I don't quite understand the reason for this behavior.
I clearly see that the speed is gaining rapidly, but I cannot understand why the original idea does not work, and what other solutions there might be that would take the same two parameters.
FixedUpdate
.fixedDeltaTime
comes from theTime.fixedDeltaTime
, and equals 0,02 = 50 Hz. Gravity is handled by dynamic Rigidbody2D. \$\endgroup\$FixedUpdate
is called like a regular event function. The timer is set in a separate method, where theIsJumping
flag is switched, there is nothing special, but this andIsGrounded
both prevent multiple jumps. No other forces affect the operation of the code shown.Rigidbody2D
has default parameters. \$\endgroup\$