Menu
CoddyTech

CharacterController.Move

Часть раздела Создание настоящих игр путешествия по Unity на Coddy. Урок 38 из 60.

CharacterController — это компонент Unity для ходьбы персонажа: капсула, которая движется только тогда, когда ваш скрипт вызывает controller.Move(motion). motion — это расстояние, на которое нужно переместиться за этот кадр, то есть скорость, умноженная на Time.deltaTime. Move скользит капсулой вдоль стен, а не сквозь них, позволяет подниматься по склонам с углом до значения Slope Limit (45 degrees) и взбираться на уступы высотой до значения Step Offset (0.3 units). Это не Rigidbody: никаких сил, гравитации, отскоков, и ничто не толкает его. Он перемещается точно туда, куда направляет Move, что и нужно для точного управления в игре.

Гравитацию нужно добавлять самостоятельно, как и поиск пола. isGrounded имеет значение true, когда при последнем вызове Move было задето что-то снизу, поэтому перемещение без движения вниз никогда не обнаружит пол. Если перемещение короче Min Move Distance контроллера (0.001), оно вообще ничего не делает, поэтому контроллер, который двигался только вбок, сразу после остановки сообщает, что он не стоит на земле. Этот курьер ходит с помощью стрелок и при каждом перемещении немного движется вниз:

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;   // всегда прижимать вниз, чтобы обнаружить пол
        controller.Move(move * Time.deltaTime);
        if (!controller.isGrounded)
        {
            Debug.Log("Off the ground");
        }
    }
}

Капсула сохраняет расстояние Skin Width (0.08) до поверхностей, которых касается, поэтому контроллер высотой 2 units на полу с координатой y = 0 находится на высоте y = 1.08, а не 1. Move начинает перемещение из точки, в которой физическая система в последний раз видела контроллер, поэтому заданное для него значение transform.position может быть отменено при следующем вызове Move: чтобы телепортировать его, задайте controller.enabled = false, переместите его, а затем снова включите.

challenge icon

Задание

Средне

Перемещай исследователя с помощью его CharacterController, чтобы стена его останавливала.

  1. В Update() создай Vector3 move из Input.GetAxisRaw("Horizontal") по оси x и Input.GetAxisRaw("Vertical") по оси z, умножив результат на speed.
  2. Задай move.y = -fallSpeed; и вызови controller.Move(move * Time.deltaTime);.
  3. Затем задай rend.material.color значение Color.green, когда controller.isGrounded, иначе — Color.red.

Нажми «Играть», подойди к стене и сойди с левого края: исследователь падает красным и приземляется зелёным. Затем нажми «Проверить».

Попробуйте сами

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()
    {
        // Перемещайте исследователя с помощью controller.Move, затем задайте его цвет в зависимости от isGrounded
    }
}

Все уроки раздела Создание настоящих игр

Потренируйтесь самостоятельно: Песочница Unity