Search Unity

Resolved 2D character controller: calculating jump speed based on jump height and gravity acceleration?

Discussion in 'Physics' started by Sinterklaas, Jan 27, 2023.

  1. Sinterklaas

    Sinterklaas

    Joined:
    Jun 6, 2018
    Posts:
    93
    I'm trying to write a method that calculates initial jump speed using the height of the jump and the gravity acceleration, for the purposes of a 2D raycast-based character controller script. I've written a method for this, but the resulting jumps only get to about 95% of their intended height. I'm not very good at physics, and I could use some help.

    Start speed method:
    Code (CSharp):
    1. public static float CalculateStartSpeed(float distance, float endSpeed, float acceleration)
    2. {
    3.     return Mathf.Sqrt(endSpeed * endSpeed - 2.0f * acceleration * distance);
    4. }
    Which I wrote by using the formula: v² = u² + 2as
    Which can be rewritten to: u² = v² - 2as
    Which in turn can be rewritten to: u = sqrt(v² - 2as)

    My speed update method looks like this:
    Code (CSharp):
    1. public static float Accelerate(float currentSpeed, float acceleration, float deltaTime)
    2. {
    3.     return currentSpeed + acceleration * deltaTime;
    4. }
    Which gets called every FixedUpdate of the CharacterController script.

    However, when I use these methods with a jump height of 7, my character only manages to reach a height of about 6.6 before falling again. Does anyone have an idea why this might be? Am I overlooking something obvious?

    Edit: Oh, and if you don't know what the problem is, but you can confirm that the methods I posted are correct, please let me know, because then at least I know the problem is somewhere else.
     
    Last edited: Jan 27, 2023
  2. Sinterklaas

    Sinterklaas

    Joined:
    Jun 6, 2018
    Posts:
    93
    Ok, so it took me like a day, but I figured it out. Turns out I did two things wrong.

    First, I made the mistake of updating my speed before updating my position. This essentially meant that the first frame of the jump was skipped, which also happens to be the frame where the speed boost is the largest. The result was a lower jump. Moving my speed update to happen after my position update fixed this problem.

    However, now my character jumped about 2% higher than he was supposed to. This is because my position update basically boiled down to:
    Code (CSharp):
    1. transform.position += jumpVelocity * deltaTime;
    Which is only correct if you move at a constant speed.
    Since my speed accelerates, I had to instead use the formula: s = ut + ½at².
    Code (CSharp):
    1. transform.position += (jumpVelocity + 0.5f * deltaTime) * deltaTime;
    This gets me a jump height within 0.005 of the intended jump height, which is good enough for my use-case.
     
    Last edited: Jan 28, 2023
  3. Nick_johny

    Nick_johny

    Joined:
    Feb 1, 2023
    Posts:
    4
    Thank you for your answer it is informative