Variable Jump + Scaled Gravity

While this is not by any means a new mechanic (variable jump) I did put a spin on it by scaling gravity, and allowing two different gravity scales for maximum design control

Variable Jump

Separate Gravity for Ascent and Descent

Separating ascent from descent gravity allows designers to really control the feel on the way UP as well as the way DOWN.

Mathematically this is achieved by drawing two parabolas and

  • taking the first half of the first graph until the apex

  • taking the second half of the second graph after the apex

Multi Jump

Using this strategy also allows for multi-jumps to have different scales either on the way up/down/both.

Double jumps are slightly less powerful (75%)

Design controls Jump Height and Time

Rather than specifying a specific velocity for the jump, which is hard for designers to visualize, instead they specify a Jump Height and Time to reach which is more visualization friendly.

if I told you the following, which is easier to visualize how high the jump will be, and how long will it take?

hard to visualize

very clear to immediately visualize

This also helps Level Design know how to make levels by not needing to calculate "well if they can jump at his speed, how high can they reach".

Jump Ascent Control

Design can specify a MIN, MAX, and TIME TO MAX for the jump such that

  1. It will take Time to Jump Max Height to reach Jump Max Height

  2. The player will always perform a minimum jump of Jump Min Height

quick ascent
floaty ascent

Jump Descent Control

Similarly design can specify a Post Jump time (which uses the Jump Max Height) to apply separate gravity on the way down

quick descent
floaty descent

Calculating Velocity & Gravity given Height & Time

We have Height and Time so we need to calculate Gravity and Initial Velocity as functions of time and height.

Projectile Motion

Let's start with the projectile motion function which gives the height of an object

It's more correct to use th (t sub h) when indicating time at height, but for simplicity of typing I'll just use t in the equations

Height at apex equation

p0 can be ignored here because the start of the jump is our actors position (can be added later).

Apex of the height is at time th :

Velocity as a function of gravity and time

We want to find velocity at a given time which is the derivative of the projectile motion function

The Apex of the jump th (time at max height) is when Velocity = 0

so we can derive Velocity as a function of gravity and time

Gravity Equation as a function of height and time

Substitute Velocity into the equation for height and solve for gravity

Velocity as a function of height and time

Since the two knowns we have are height and time substitute gravity back in to find Velocity as a function of height and time

Can find Velocity & Gravity at any Height & Time

Now we have our two equations as functions of time

Velocity

Gravity

Which means for any given Height and Time we can find the corresponding Velocity and Gravity needed

Gravity Scale vs Gravity

Preface

You might be thinking "but wait Unreal already defines gravity as 9.8m/s^2 (or 980cm/s^2 for Unreal)" and is going to apply that gravity every tick?

Yes, I'm relying on the CharacterMovementComponent to apply a constant gravity, but what we can control is actually Gravity Scale instead of gravity itself.

Slight modification to Gravity equation

Since we want gravity as a Scale and not a flat value, in the previous gravity equation

We can get the scale by dividing by the engine defined gravity constant UPhysicsSettings::Get()->DefaultGravityZ which we can call DefaultGravityZ

so our equation really becomes

This will provide a scalar that represents whether gravity is higher or lower than the default, which we can set in code.

Code Example

Velocity & Gravity functions

Cache gravity scales up front

At the start of the game we have our given designer values for Jump Max Height and Time...etc so we can pre-calculate a number of variables for

  • Default Gravity

  • Starting Gravity Scale

  • Max Pre Jump (ascent) Gravity Scale

  • Min Pre Jump (ascent) Gravity Scale

  • Post Jump (descent) Gravity Scale

Handle Variable Jump (ascent)

Variable jump height is achieved by calculating a gravity scale between the Min and Max gravity scales based on how long the input was held

Jump

Instantaneous Velocity is applied to make it to the height in the given time, and the appropriate gravity scale is also applied

Switch Gravity at Jump Apex (descent)

Technically we immediately enter the MovementMode(MOVE_Falling) state so that UE's starts applying gravity immediately.

We override PhysFalling which will get executed upon switching movement mode for a number of reasons other than jump, but for jumping its to check for when we switch from Positive to Negative velocity which means we're at the Apex of the jump.

Here is where we switch from our (ascent) Jump Gravity scale to the (descent) fall gravity

Last updated