Menu
CoddyTech

CharacterController.Move

Teil des Abschnitts Echte Spiele entwickeln der Unity-Journey von Coddy. Lektion 38 von 60.

Ein CharacterController ist Unitys Komponente für eine laufende Figur: eine Kapsel, die sich nur bewegt, wenn dein Skript controller.Move(motion) aufruft. motion ist die Strecke, die sie sich in diesem Frame bewegen soll, also eine Geschwindigkeit multipliziert mit Time.deltaTime. Move gleitet mit der Kapsel an Wänden entlang, anstatt durch sie hindurchzugehen, bewegt sie Steigungen mit einem Winkel von bis zu ihrem Slope Limit (45 Grad) hinauf und lässt sie auf Kanten mit einer Höhe von bis zu ihrem Step Offset (0.3 Einheiten) steigen. Der CharacterController ist kein Rigidbody: Es gibt keine Kräfte, keine Schwerkraft, kein Abprallen, und nichts stößt ihn an. Er bewegt sich genau dorthin, wohin Move ihn schickt – genau das braucht eine präzise Spielsteuerung.

Die Schwerkraft musst du selbst hinzufügen, ebenso wie die Erkennung des Bodens. isGrounded ist true, wenn der letzte Move etwas unterhalb berührt hat. Eine Bewegung ohne Abwärtskomponente findet den Boden also nie. Ein Move, der kürzer als die Min Move Distance des Controllers (0.001) ist, bewirkt überhaupt nichts. Deshalb meldet ein Controller, der nur seitwärts bewegt wurde, sobald er stillsteht, dass er nicht am Boden ist. Dieser Kurier läuft mit den Pfeiltasten und drückt sich bei jeder Bewegung ein wenig nach unten:

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;   // immer nach unten drücken, damit der Boden erkannt wird
        controller.Move(move * Time.deltaTime);
        if (!controller.isGrounded)
        {
            Debug.Log("Off the ground");
        }
    }
}

Die Kapsel hält einen Abstand von ihrer Skin Width (0.08) zu dem ein, was sie berührt. Ein 2 Einheiten hoher Controller auf einem Boden bei y = 0 ruht daher bei y = 1.08 und nicht bei 1. Move geht von der Position aus, an der die Physik den Controller zuletzt gesehen hat. Eine Änderung von transform.position kann deshalb durch den nächsten Move rückgängig gemacht werden. Um ihn zu teleportieren, setze controller.enabled = false, bewege ihn und aktiviere ihn anschließend wieder.

challenge icon

Aufgabe

Mittel

Bewege die Erkundungsfigur mit ihrem CharacterController, damit die Wand sie stoppt.

  1. Erstelle in Update() Vector3 move aus Input.GetAxisRaw("Horizontal") auf der x-Achse und Input.GetAxisRaw("Vertical") auf der z-Achse, multipliziert mit speed.
  2. Setze move.y = -fallSpeed; und rufe controller.Move(move * Time.deltaTime); auf.
  3. Setze dann rend.material.color auf Color.green, solange controller.isGrounded gilt, andernfalls auf Color.red.

Drücke „Spielen“, gehe gegen die Wand und über den linken Rand hinaus: Die Erkundungsfigur fällt rot herunter und landet grün. Drücke dann „Prüfen“.

Probier es selbst

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()
    {
        // Bewege den Explorer mit controller.Move und färbe ihn anschließend abhängig von isGrounded ein
    }
}

Alle Lektionen in Echte Spiele entwickeln

Übe selbstständig: Unity-Playground