Menu
CoddyTech

Jump

Lesson 3 of 20 in Coddy's Unity Game: Sky Lanes course.

Next the runner jumps. A CharacterController has no gravity of its own: your script keeps a vertical speed and moves by it every frame.

Gravity changes that speed every frame. When the runner stands on the ground (controller.isGrounded), keep a small downward speed of -2 so it stays pressed onto the road:

if (controller.isGrounded && fallSpeed < 0f) fallSpeed = -2f;
fallSpeed += gravity * Time.deltaTime;

To reach a height h under gravity g, a jump starts with the speed Mathf.Sqrt(h * -2f * g). With a jump height of 1.6 and a strong gravity of -40 the runner jumps high and comes down fast, which suits a game where things come at you:

bool jump = Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space);
if (jump && controller.isGrounded)
{
    fallSpeed = Mathf.Sqrt(jumpHeight * -2f * gravity);
}

The move now has a y part too: fallSpeed * Time.deltaTime.

challenge icon

Challenge

Easy
  1. Add public float jumpHeight = 1.6f;, public float gravity = -40f; and private float fallSpeed; to Runner.
  2. After the lane keys, read the jump keys (W, Up, Space) and jump only when controller.isGrounded.
  3. Before targetX, add the two gravity lines above.
  4. Make the move new Vector3(x - transform.position.x, fallSpeed * Time.deltaTime, 0f).

Try it yourself

using UnityEngine;

public class Runner : MonoBehaviour
{
    public float laneWidth = 2.5f;
    public float laneSpeed = 16f;

    public int lane;

    private CharacterController controller;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) lane = Mathf.Max(-1, lane - 1);
        if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) lane = Mathf.Min(1, lane + 1);

        float targetX = lane * laneWidth;
        float x = Mathf.MoveTowards(transform.position.x, targetX, laneSpeed * Time.deltaTime);
        Vector3 move = new Vector3(x - transform.position.x, 0f, 0f);
        controller.Move(move);
    }
}

All lessons in Unity Game: Sky Lanes

Practice on your own: Unity playground