Up until now our character’s movement has been constrained to the X and Z axes, with no interaction whatsoever with the third dimension. Even walking off the edge of the stage we created has no effect—our controller is able to continue happily moving around in the world despite their being no solid ground beneath her. To fix this, we’ll add the ability to jump, as well as handle cases where our controller has fallen off the stage.
Let’s cover jumping first. Before writing any code, we need to figure out what it means to make our controller “jump”. Common sense would give us an answer along the lines of “make our character go up and down,” but let’s narrow down some specific concepts. To do this, let’s take a look at Super Mario Bros.
When the user pushes the jump button, Mario is propelled upwards, and then pulled back down to the ground, with a trajectory similar to that of a ball thrown into the air. When the ball leaves your hand, it has an initial velocity that is constantly decreased due to the force of gravity exerted on it. Let’s try to put this into code. When the player pushes the jump button, we’ll want to set our controller’s upward velocity to some predetermined value…except currently, our controller has no velocity value to set! If we recall this line below
gameObject.GetComponent<CharacterController>().Move(transform.TransformDirection(input * speed * Time.deltaTime));
We can see that we’re simply moving our controller based on the input provided by the player for the current frame. There’s no concept of velocity or acceleration. We’ll need to keep track of our jumping velocity, so let’s create a new variable.
private float yVelocity = 0;
This will determine how fast she is currently moving up and down, where positive values are up, and negative down. As well, we’ll need some values to determine how fast our initial jump speed is, and how powerful the force of gravity is.
public float jumpSpeed = 15.0f; public float gravity = 30.0f;
Alright! Now that we’ve gotten everything set up, we can return to our original idea: when the user pushes Jump, we set out yVelocity to our jumpSpeed.
if (Input.GetButtonDown("Jump")) { yVelocity = jumpSpeed; }
Next, we’ll need to make sure the CharacterController.Move method is provided with some additional data to make sure it moves our controller up and down based on the current value of yVelocity. Modify the movement line to be the following
gameObject.GetComponent<CharacterController>().Move(transform.TransformDirection(input * speed * Time.deltaTime + yVelocity * Vector3.up * Time.deltaTime));
We’ve added a new operation at the end. We take Vector3.up (which you will recall is shorthand for Vector3(0, 1, 0)) and scale it by our current yVelocity, and then add that value to the rest of the input velocity. As always, we multiple by deltaTime to make the movement framerate independent. Let’s run it in Unity. Start the game, and then push the space bar…and you’ll see your controller float off into the heavens. That’s the first half of jumping completed! What we have now is essentially what jumping would look like in a zero-gravity environment, as if our controller were rocketing around in space.

Farewell beautiful friend.
Looking back at the animation of Mario jumping, we can see that gravity is exerted on him constantly, accelerating him downwards. So let’s apply an acceleration on our own controller by modifying the yVelocity value. Add the following line anywhere above our movement call.
yVelocity -= gravity * Time.deltaTime;
Run the game again, and you’ll be able to jump around to your heart’s content! You’ll probably notice that currently, if you try to walk off the edge of the stage (or off one of the blocks in the level), the controller is pulled downwards extremely fast. This is definitely not the behavior we want for the final product, and is a problem we’ll tackle in the next lesson.