Menu
CoddyTech

CharacterController.Move

Parte de la sección Creación de juegos reales del Journey de Unity de Coddy. Lección 38 de 60.

Un CharacterController es el componente de Unity para un personaje que camina: una cápsula que solo se mueve cuando tu script llama a controller.Move(motion). motion es la distancia que se debe recorrer en este fotograma, por lo que es una velocidad multiplicada por Time.deltaTime. Move desliza la cápsula a lo largo de las paredes en lugar de atravesarlas, sube pendientes de hasta su límite de pendiente (45 grados) y sube escalones de hasta su desplazamiento de escalón (0.3 unidades). No es un Rigidbody: no hay fuerzas, gravedad ni rebotes, y nada lo empuja. Va exactamente adonde lo envía Move, que es lo que necesitan los controles precisos de los juegos.

La gravedad debes añadirla tú, igual que detectar el suelo. isGrounded es true cuando el último Move tocó algo por debajo, así que un movimiento sin componente hacia abajo nunca detecta el suelo. Un Move más corto que la distancia mínima de movimiento del controlador (0.001) no hace absolutamente nada, por lo que un controlador que solo se mueve de lado informa que no está en el suelo en cuanto se queda quieto. Este mensajero camina con las flechas y aplica un poco de fuerza hacia abajo en cada movimiento:

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;   // presiona siempre hacia abajo para detectar el suelo
        controller.Move(move * Time.deltaTime);
        if (!controller.isGrounded)
        {
            Debug.Log("Off the ground");
        }
    }
}

La cápsula mantiene una distancia equivalente a su ancho de piel (0.08) de aquello que toca, así que un controlador de 2 unidades de altura sobre un suelo en y = 0 queda en y = 1.08, no en 1. Además, Move parte de la posición en la que la física vio por última vez al controlador, así que una transform.position establecida en él puede deshacerse con su siguiente Move: para teletransportarlo, establece controller.enabled = false, muévelo y vuelve a activarlo.

challenge icon

Desafío

Intermedio

Mueve al explorador con su CharacterController para que la pared lo detenga.

  1. En Update(), crea Vector3 move a partir de Input.GetAxisRaw("Horizontal") en x y Input.GetAxisRaw("Vertical") en z, multiplicados por speed.
  2. Asigna move.y = -fallSpeed; y llama a controller.Move(move * Time.deltaTime);.
  3. Después, asigna rend.material.color a Color.green mientras controller.isGrounded sea verdadero; de lo contrario, a Color.red.

Pulsa «Jugar», camina hacia la pared y sal por el borde izquierdo: el explorador cae en rojo y aterriza en verde. Después, pulsa «Comprobar».

Pruébalo tú mismo

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()
    {
        // Camina con controller.Move y luego colorea al explorador según isGrounded
    }
}

Todas las lecciones de Creación de juegos reales

Practica por tu cuenta: Playground de Unity