0
\$\begingroup\$

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.

\$\endgroup\$
7
  • \$\begingroup\$ Does the player character keep accelerating regardless of how long the jump arrow is pressed? \$\endgroup\$
    – Questor
    Commented Feb 6 at 23:04
  • \$\begingroup\$ No. It's exactly the logic that plays in FixedUpdate. fixedDeltaTime comes from the Time.fixedDeltaTime, and equals 0,02 = 50 Hz. Gravity is handled by dynamic Rigidbody2D. \$\endgroup\$
    – Demexis
    Commented Feb 6 at 23:32
  • \$\begingroup\$ Just asking cuz I can't see the context for how/when FixedUpdate is called/ how, where the timer is set etc...... And if you allow the player to jump forever... \$\endgroup\$
    – Questor
    Commented Feb 6 at 23:39
  • \$\begingroup\$ Player can jump only when the character is "grounded". FixedUpdate is called like a regular event function. The timer is set in a separate method, where the IsJumping flag is switched, there is nothing special, but this and IsGrounded both prevent multiple jumps. No other forces affect the operation of the code shown. Rigidbody2D has default parameters. \$\endgroup\$
    – Demexis
    Commented Feb 7 at 0:36
  • 1
    \$\begingroup\$ Some games implement a variable height jump not by adding velocity, but by decreasing acceleration due to gravity during the initial frames of the jump, depending on how long the button is held. You may find that framing it that way makes it easier to avoid some of the unwanted behaviour you're observing. \$\endgroup\$
    – DMGregory
    Commented Feb 7 at 1:18

2 Answers 2

0
\$\begingroup\$

Your math is not mathing.

sqrt() is not a linear operation. This is what the slope of a sqrt(x) looks like: sqrt(x) graph

This is what a linear operation would look like

graph of X

If I want to jump up 1 unit of height with a gravity of 10 units/s then the velocity I Need is sqrt(2 * 10 * 1) = 4.47214... If I want to jump up 3 units of height then the velocity I need is sqrt(2 * 10 * 3) or 7.74597... Which is not 3 * 4.47214.

\$\endgroup\$
-1
\$\begingroup\$

You're adding to the speed in every FixedUpdate with this line. character.rigidbody2D.velocity.y += jumpVelocityY;

What I'd do is treat it like a regular instant velocity, fixed-height jump. Then, if the jump button is released, gravity would increase to end the jump earlier.

\$\endgroup\$
3
  • \$\begingroup\$ This is just an approximate code snippet. In fact, it checks whether the player is still pressing the button, and if not, then the code does not wait for the timer to expire, but immediately interrupts further addition of velocity. Gravity is constant and cannot change for individual objects. \$\endgroup\$
    – Demexis
    Commented Feb 6 at 22:27
  • \$\begingroup\$ Even so, there's no reason to keep adding velocity when the jump button is still pressed, it's a jump not a rocket launch. Instead of changing the gravity, you can instead add additional downward acceleration, or just make the upwards velocity 0 when the button is released. It depends on what feel you're going for. \$\endgroup\$
    – Ifn47
    Commented Feb 6 at 22:35
  • \$\begingroup\$ Three points: 1) In a 2D platformer you'll want to have height control. 2) You don't want to force this through external properties that might affect how other mechanics work. 3) As a game designer, you want to have direct and precise control over the height range, without ambiguous forces. \$\endgroup\$
    – Demexis
    Commented Feb 6 at 22:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .