Menu
CoddyTech

CharacterController.Move

Part of the Building Real Games section of Coddy's Unity journey. Lesson 37 of 56.

A CharacterController is Unity's component for a walking character: a capsule that moves only when your script calls controller.Move(motion). motion is the distance to move this frame, so it is a speed times Time.deltaTime. Move slides the capsule along walls instead of through them, walks up slopes up to its Slope Limit (45 degrees) and steps onto ledges up to its Step Offset (0.3 units). It is not a Rigidbody: no forces, no gravity, no bounce, and nothing pushes it. It goes exactly where Move sends it, which is what tight game controls need.

Gravity is yours to add, and so is finding the floor. isGrounded is true when the last Move touched something below, so a move with no downward part never finds the floor. A Move shorter than the controller's Min Move Distance (0.001) does nothing at all, so a controller moved only sideways reports that it is not grounded as soon as it stands still. This courier walks with the arrows and presses down a little in every move:

public class Courier : MonoBehaviour
{
    public float speed = 6f;
    CharacterController controller;

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

    void Update()
    {
        Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
        move.y = -2f;   // always press down, so the floor is found
        controller.Move(move * Time.deltaTime);
        if (!controller.isGrounded)
        {
            Debug.Log("Off the ground");
        }
    }
}

The capsule keeps its Skin Width (0.08) away from what it touches, so a 2 unit tall controller on a floor at y = 0 rests at y = 1.08, not 1. And Move starts from where the physics last saw the controller, so a transform.position set on it can be undone by its next Move: to teleport it, set controller.enabled = false, move it, and enable it again.

challenge icon

Challenge

Medium

The explorer stands on a stone platform with a wall at the back and a drop on the left. Write Explorer.cs on the Player, which has a CharacterController. The Inspector sets speed (4) and fallSpeed (3), and Start() already finds the controller and the explorer's Renderer.

  • The arrows (or WASD), read with the raw axes, walk it with controller.Move at speed units a second: left and right along x, up and down along z. The wall must stop it.
  • Every move also goes down at fallSpeed units a second, so the explorer stays on the platform and drops off its edge.
  • While the controller is grounded, the explorer is Color.green; while it is not, Color.red.

Press Play, walk into the wall and off the edge, then Check.

Try it yourself

using UnityEngine;

public class Explorer : MonoBehaviour
{
    public float speed = 4f;
    public float fallSpeed = 3f;

    CharacterController controller;
    Renderer rend;

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

    void Update()
    {
        // Walk with controller.Move, then color the explorer by isGrounded
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Building Real Games