Probably the most important feature of any platformer game is jumping. We have spent quite a few weeks iterating on the feel of jumping mechanics in The Lightbringer.
We have written our own controllers, tested existing ones from the asset store and the mix of both. At the end we have used Lightbug’s Character Controller Pro as a base and added our own custom functionalities on top of it.
To help other indie developers with their adventures into building awesome games I’d like to share how we achieved our (not so) perfect jump.
We have 3 parameters that determine how far, high and fast our character jumps. These are: JumpReach, JumpTime and JumpHeight
These parameters are set by the designer when balancing the feel. We use those params to calculate 3 other properties:
ForwardSpeed = 0.5f * JumpReach / JumpTime; Acceleration = 2 * JumpHeight / (JumpTime * JumpTime); InitialVelocity = Acceleration * JumpTime;
And those properties let us calculate 2 velocities at any given moment:
The one used when the players is jumping up:
CurrentVelocity(float time) => InitialVelocity — Acceleration * Mathf.Abs(time);
And the other one used when the plays is falling down:
CurrentDownVelocity(float time) => Acceleration * time;
Jumping in The Lightbringer
Now we can use this to actually perform jumps.
At the beginning of the jump we set our vertical speed like this:
VerticalMovement = Vector3.up * InitialVelocity;
Now we have begun a process of jumping up. Now in the FixedUpdate we calculate current vertical and horizontal speeds like this:
HorizontalMovement = direction * ForwardSpeed; VerticalMovement = Vector3.up * CurrentVelocity(Time.time — jumpStartTime));
After half of the time configured in the param “JumpTime” we stop jumping up. Here you have a choice — if you want you can add a brief “hang in the air” time, we use 0.1f in which you don’t move either up or down, only forward.
Then we begin a process of jumping down.
fallStartTime = 0f; HorizontalMovement = 0f;
And now in the FixedUpdate we calculate current vertical and horizontal speeds like this:
HorizontalMovement = direction * ForwardSpeed; VerticalMovement = Vector3.down * CurrentDownVelocity(Time.time — fallStartTime);
And we fall down until we detect a collision with the ground.
And that’s it. Using those techniques you can create a really nice jump feel.
Enough jumping for today ;)
If you guys have any question feel free to jump on our Discord: https://discord.gg/bukwCw7