Gamasutra is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Gamasutra: The Art & Business of Making Gamesspacer
arrowPress Releases
If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 

Designing a Jump in Unity

by Daniel Fineberg on 08/25/15 01:22:00 pm   Featured Blogs

8 comments Share on Twitter    RSS

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

 

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
rigidbody.AddForce(jumpVector);
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;
rigidbody.AddForce(jumpVector, ForceMode2D.Impulse);
 
//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);
rigidbody.AddForce(thisFrameJumpVector);
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.

 


Related Jobs

Backflip Studios
Backflip Studios — Boulder, Colorado, United States
[06.19.19]

Senior Cloud Software Engineer
Gear Inc.
Gear Inc. — Hanoi, Vietnam
[06.18.19]

Mobile Games Tools Producer
Genies Inc
Genies Inc — Venice, California, United States
[06.18.19]

*Principal Engineer - Graphics Programming & Rendering Engine*
Disbelief
Disbelief — Chicago, Illinois, United States
[06.18.19]

Junior Programmer, Chicago





Loading Comments

loader image