Right, well there’s lots of different ways to do jumps, and it depends very much on the exact effect you’re after. It strikes me that what you are probably looking for here is:
- If the user just ‘taps’ the key, the player jumps to some minimum height
- If the user holds the key, the end jump height will get higher, up to some maximum value
So we end up really with 3 variables:
- the minimum height
- the maximum height
- how long the player has to hold the jump key to achieve maximum height
Before worrying about achieving precise heights (as that requires some slightly awkward maths), lets replace the problem with:
- an initial jump velocity
- an initial acceleration
- how long the player can hold the jump key for (before it stops having an effect)
So when a jump first begins we must do something like:
if (Input.GetKeyDown ("space") && contactGround)
{
//set initial rigid body velocity
curr_vel = rigidbody.velocity;
curr_vel.y = initial_jump_velocity
rigidbody.velocity = curr_vel
//store that we are jumping, and record the time we started
is_jumping = true
jump_start_time = Time.time
}
With that code, I now have the player initially pinging into the air, and know that I am jumping, and when I started jumping. Next:
//if jumping, check if key is held down
if (is_jumping && Input.GetKey("space"))
{
//still holding the key, so check if we're within our maximum key held time
time_since_jump = Time.time - jump_start_time
if(time_since_jump < max_jump_time)
{
//calculate a value that is 1 at the start of the jump, and 0 at max_jump_time
float t = 1-time_since_jump / max_jump_time;
//(we might at this stage do something like t = t*t, which would make the fall off a curve)
//from that, calculate an amount we're allowed to accelerate the player by (which fades to 0)
acceleration = max_acceleration * t;
//apply acceleration
curr_vel = rigidbody.velocity;
curr_vel.y += acceleration;
rigidbody.velocity = curr_vel;
}
}
This is common pattern you’ll see across a lot of games. I first calculate how long it’s been since I started jumping. if I’m within a given time limit, I calculate a number (the interpolator, often named ‘t’) that is 1 at the start, and 0 at the end of my time limit.
Using the interpolator, I then calculate how much I can accelerate the player by. As I mention in the comments, it’s not unusual to square or use mathf.pow on the interpolator, which would make the acceleration fall off in different ways - one to experiment with to get the feel you want.
That alone should get you going. It doesn’t allow you to specify an exact max height, but by fiddling with the initial jump height and acceleration you should be able to tune it nicely.
If you really want to calculate precise values, then you’ll need to take it a step further, and calculate (based on gravity) the exact linear velocity required to acheive a given height. In this scenario, each frame we would know:
- the difference between our current height and our target height
- how much more time is left for us to reach the target height
You then have to plug it into the quadratic equation:
s = ut + 0.5at^2
where s is the change in height we need, a is acceleration (aka gravity), t is how much time we have left, and u is the value we’re interested in - how fast should we be going?
which gives us:
u = (s - 0.5at^2)/t
Each frame while the jump key was held, you’d gradually increase the target height, calculate the velocity required, and then apply it. I don’t quite have time to write the exact code for this, but to be honest, I’d just go for the first approach and tinker with it - start by tuning a nice and satisfying small ‘single tap’ jump, then fiddle with the acceleration (and potentially what you do with the interpolator) until the max jump feels good.