# Designing a Jump in UnityDesigning a Jump in Unity

An analysis of different jump models in 2D games with code examples for Unity.

Daniel Fineberg, Blogger

August 25, 2015

Cloud Critters is all about jumping. Our goal was to combine the one-touch simplicity of Flappy Bird and Don’t Touch the Spikes with the nuance and high-score potential of arcade games such as Geometry Wars.

The jump in Flappy Bird is a fixed size, sending the player a certain distance every time. We decided early in the development of Cloud Critters that we wanted a jump with variable height and power - something closer to Super Mario or Metroid. This would give the player more control over their positioning.

Here is a breakdown of the process we went through to get a jump that felt just right, with some simplified code examples in C# for Unity.

NOTE:

For the sake of demonstration, each of these JumpRoutine coroutines are called by this Update:

void Update()

{

if(jumpButtonDown && !jumping)

{

jumping = true;

StartCoroutine(JumpRoutine());

}

}

In a real project, you would ideally handle all physics-related behaviour in FixedUpdate.

## The Constant Force

IEnumerator JumpRoutine()

{

rigidbody.velocity = Vector2.zero;

float timer = 0;

while(jumpButtonPressed && timer < jumpTime)

{

//Add a constant force every frame of the jump

timer += Time.deltaTime;

yield return null;

}

jumping = false;

}

Pros:

A big difference between the largest and smallest jump gives the player a lot of control over the jump height/distance.

Cons:

Adding the same force every frame causes the character to accelerate over time, giving the jump a heavy jetpack feel.

## The Zero Gravity

IEnumerator JumpRoutine()

{

//Set the gravity to zero and apply the force once

float startGravity = rigidbody.gravityScale;

rigidbody.gravityScale = 0;

rigidbody.velocity = jumpVector;

float timer = 0f;

while(jumpButtonPressed && timer < jumpTime)

{

timer += Time.deltaTime;

yield return null;

}

//Set gravity back to normal at the end of the jump

rigidbody.gravityScale = startGravity;

jumping = false;

}

Pros:

No acceleration over time - the character reaches maximum jump speed on the first frame. This is closer to the jump in the old Super Mario games.

Cons:

The character keeps going for several frames after the player lets go of the jump button. This means the minimum jump is quite large.

## The Velocity Cut

IEnumerator JumpRoutine()

{

//Add force on the first frame of the jump

rigidbody.velocity = Vector2.zero;

//Wait while the character's y-velocity is positive (the character is going

//up)

while(jumpButtonPressed && rigidbody.velocity.y > 0)

{

yield return null;

}

//If the jumpButton is released but the character's y-velocity is still

//positive...

if(rigidbody.velocity.y > 0)

{

//...set the character's y-velocity to 0;

rigidbody.velocity = new Vector2(rigidbody.velocity.x, 0);

}

jumping = false;

}

Pros:

Very precise control over the peak of the jump. The character starts falling as soon as the button is released.

Cons:

While the maximum jump arc is smooth, smaller jump arcs have a sharp peak that doesn’t feel so nice.

## The Just Right

IEnumerator JumpRoutine()

{

rigidbody.velocity = Vector2.zero;

float timer = 0;

while(jumpButtonPressed && timer < jumpTime)

{

//Calculate how far through the jump we are as a percentage

//apply the full jump force on the first frame, then apply less force

//each consecutive frame

float proportionCompleted = timer / jumpTime;

Vector2 thisFrameJumpVector = Vector2.Lerp(jumpVector, Vector2.zero, proportionCompleted);

timer += Time.deltaTime;

yield return null;

}

jumping = false;

}

Pros:

The player has a lot of control over the height of the jump and the arc of the jump is always perfectly smooth. No floaty jetpack feel either.

Cons:

NONE IT’S PERFECT ^.^

And that's how we chose our jump! Obviously which jump model suits your game is entirely up to you. Download Cloud Critters on android or iOS to see how it turned out.