Menu
CoddyTech

The Course

Part of the Building Real Games section of Coddy's Unity journey. Lesson 49 of 60.

This chapter builds a 3D platformer. You run and jump across floating platforms, ride one that glides, touch checkpoints so a fall does not send you back to the start, collect gems counted on screen, cross the finish into the next level and try to beat your best time. The game is five scripts, in the project from the start: Player, MovingPlatform, Checkpoint, Gem and FinishLine. The last four are empty for now, and each lesson fills one in. The player is a CharacterController steered with the Input System's actions, and the camera is its child, so it follows without a script.

A CharacterController moves in two ways. Move(motion) moves it by a distance and adds nothing, so gravity, jumps and Time.deltaTime are the script's job, as in the Character Controller chapter. SimpleMove(speed) takes a speed in units per second, scales it by the frame's time itself and adds gravity; it ignores the y you pass, so a character moved with it falls off ledges but can never jump. This sheepdog in a herding game seen from above needs no jump, so SimpleMove and the Move action are its whole script:

using UnityEngine;
using UnityEngine.InputSystem;

public class Sheepdog : MonoBehaviour
{
    [SerializeField] private float speed = 6f;
    private CharacterController controller;
    private InputAction moveAction;

    void Start()
    {
        controller = GetComponent<CharacterController>();
        moveAction = InputSystem.actions.FindAction("Move");
    }

    void Update()
    {
        Vector2 input = moveAction.ReadValue<Vector2>();
        controller.SimpleMove(new Vector3(input.x, 0f, input.y) * speed);
    }
}

The platformer's player has to jump, so it keeps its own vertical velocity and moves with Move, reading the Move and Jump actions instead of the Input class. Unity recommends one call to Move or SimpleMove per frame: the walk and the fall go into the same call, and isGrounded then describes that whole move.

challenge icon

Challenge

Medium

Make the player walk, jump and fall.

  1. In Start(), find Move and Jump with InputSystem.actions.FindAction.
  2. In Update(), walk at speed: Move's x along x, its y along z.
  3. Add gravity * Time.deltaTime to velocity.y, -2f while grounded and falling. Jump, while grounded, sets it to Mathf.Sqrt(jumpHeight * -2f * gravity).
  4. Call controller.Move((move + velocity) * Time.deltaTime) once.

Press Play: jump to the first platform. Then Check.

Try it yourself

using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
    [SerializeField] private float speed = 5f;
    [SerializeField] private float jumpHeight = 1.5f;
    [SerializeField] private float gravity = -9.81f;

    private CharacterController controller;
    private Vector3 velocity;

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

    void Update()
    {
        // walk with the Move action, jump with the Jump action, fall with gravity
    }
}

All lessons in Building Real Games

Practice on your own: Unity playground