Menu
CoddyTech

CharacterController.Move

Parte da seção Criando Jogos de Verdade do Journey de Unity da Coddy. Lição 38 de 60.

Um CharacterController é o componente do Unity para um personagem que anda: uma cápsula que só se move quando seu script chama controller.Move(motion). motion é a distância a percorrer neste quadro, ou seja, uma velocidade multiplicada por Time.deltaTime. Move desliza a cápsula ao longo das paredes, em vez de atravessá-las, sobe rampas até seu Slope Limit (45 graus) e sobe em degraus de até seu Step Offset (0.3 unidades). Ele não é um Rigidbody: não há forças, gravidade nem quique, e nada o empurra. Ele vai exatamente para onde Move o envia, o que é necessário para controles precisos no jogo.

A gravidade fica por sua conta, assim como encontrar o chão. isGrounded é true quando o último Move tocou algo abaixo, então um movimento sem componente para baixo nunca encontra o chão. Um Move menor que a Min Move Distance do controlador (0.001) não faz absolutamente nada, então um controlador que se moveu apenas para os lados informa que não está no chão assim que fica parado. Este entregador anda com as setas e aplica uma pequena força para baixo em cada movimento:

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;   // sempre aplica uma força para baixo, para que o chão seja detectado
        controller.Move(move * Time.deltaTime);
        if (!controller.isGrounded)
        {
            Debug.Log("Off the ground");
        }
    }
}

A cápsula mantém a distância de Skin Width (0.08) em relação ao que toca, então um controlador de 2 unidades de altura em um chão em y = 0 fica em y = 1.08, não em 1. E Move começa de onde a física viu o controlador pela última vez, então um transform.position definido nele pode ser desfeito pelo próximo Move: para teleportá-lo, defina controller.enabled = false, mova-o e ative-o novamente.

challenge icon

Desafio

Médio

Mova o explorador com seu CharacterController, para que a parede o pare.

  1. Em Update(), crie Vector3 move a partir de Input.GetAxisRaw("Horizontal") no eixo x e de Input.GetAxisRaw("Vertical") no eixo z, multiplicado por speed.
  2. Defina move.y = -fallSpeed; e chame controller.Move(move * Time.deltaTime);.
  3. Em seguida, defina rend.material.color como Color.green enquanto controller.isGrounded; caso contrário, como Color.red.

Pressione “Jogar”, caminhe em direção à parede e para fora da borda esquerda: o explorador cai vermelho e aterrissa verde. Depois, pressione “Verificar”.

Experimente você mesmo

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()
    {
        // Movimente o explorador com controller.Move e depois defina sua cor de acordo com isGrounded
    }
}

Todas as lições de Criando Jogos de Verdade

Pratique por conta própria: Playground de Unity