0
votes

I am working on a character controller for a 2d-platformer I am using Unity3D to implement it using my own physics (not the standard physics and the RigidBody2D component), anyway I finished it mostly but the problem is the jump, it is satisfying but I want the character to stay a little bit longer in the air when it reaches the peak of the jump, but without using a timer or so, what I mean by that, I want the character to raise slower when it gets close to the jump peak, so the jump curve gets wider.

The way I handle the velocity and movement is so: - I have a Vector2 velocity that represent the current velocity, it is set each frame depending on the current state of the character(Walking, Running, Idle,...) - I have a float gravity which is a fixed float representing the gravity - When the player jumps, I set its velocity.y to jumpVelocity and each frame, I subtract (gravity * Time.DeltaTime) from it.

The jump curve I get:

enter image description here

The jump curve I want:

enter image description here

Anyway easy way (Changing a factor or adding a variable or so) to achieve that without rewriting 50% of my code? Thanks in advance :)

With (gravity*time^2) as mentioned in the comments:

enter image description here

3
Try decreasing both gravity and jumpVelocityRuzihm
From a physics standpoint couldn't you just increase the horizontal velocity to achieve this goal?plum 0
@Ruzihm actually decreasing only the gravity is enough to achieve that curve but can't change it, the gravity in my code is calculated from 2 other variables which are maxJumpHeight and timeToJumpApex....Muhammad Nihad
@plum0 From a physics perspective: you're right, from a game perspective: no! the horizontal velocity here is the air movement speed of the player, which just fits the game and cannot be changed simplyMuhammad Nihad
I solved the problem, thanks a lot guys :) problems of this kind are hard to solve because they are related to game feel more than maths and real world physics so usually normal physics equations don't solve theme, instead, one should try to balance variables and tweak values in a way that doesn't affect other things until it feels right, thanks again :)Muhammad Nihad

3 Answers

1
votes

The time until reaching the peak is computed by setting

jumpVelocity - time * gravity = 0,

i.e.

time = jumpVelocity / gravity.

If you want your character to stay in the air for a longer time, you can increase the jumpVelocity or decrease the gravity.

However, this also leads to higher jumps.

The height of the jump is (https://en.wikipedia.org/wiki/Linear_motion#Equations_of_kinematics)

height = jumpVelocity * time - gravity/2 * time^2.       (*)

With time from above, you get

height = jumpVelocity^2 / (2*gravity),

which with the time above yields

time = 2*height / jumpVelocity.       (**)

Thus, to e.g. jump twice as long while keeping the height constant, you have to multiply jumpVelocity by 0.5 due to (**) and gravity by 0.25 due to (*).

0
votes

You should change the ratio of horizontal and vertical velocity. So you could either leave gravity and jump velocity untouched and increase the horizontal velocity, or decrease both gravity and jumping velocity (proportionally).

0
votes

There is a simple solution that I implemented after changing the code a little bit... expanding on the method of Sebastian Lague (An amazing youtuber), it is possible now to scale the curve horizontally (using timeToJumpApex variable) and vertically (using maxJumpHeight variable):

gravity = -(2 * maxJumpHeight) / Mathf.Pow(timeToJumpApex, 2);
maxJumpVelocity = Mathf.Abs(gravity) * timeToJumpApex;

This method will also calculate the gravity for you... Anyway my jump still doesn't feel that good yet, but that is not related to maths and physics equations nor to implementation problems, but as it turned out this curve is not the best one for a platformer jump...

Edit: The way I apply gravity to velocity didn't change, so:

velocity += (gravity * Time.deltaTime);