Menu
CoddyTech

Движение в направлении взгляда

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

Когда камера смотрит на игрока под углом, стрелки должны перемещать игрока так, как это отображается на экране: при нажатии вверх игрок уходит от камеры, при нажатии вправо — движется вправо относительно камеры. Оси мира дают такой результат только тогда, когда камера смотрит вдоль +z. Поэтому создайте направление движения на основе направлений самой камеры: cam.forward и cam.right.

Сначала их нужно скорректировать. У камеры, направленной вниз на игрока, forward указывает в землю, поэтому задайте для y значение 0, чтобы оставить только составляющую вдоль земли. Получившийся вектор будет короче 1 — примерно 0.87 для камеры, наклонённой вниз на 30 градусов, — и игрок будет двигаться медленнее, поэтому нормализуйте его. Этот персонаж следует за основной камерой, которая смотрит вниз на угол уровня:

Transform cam = Camera.main.transform;

Vector3 forward = cam.forward;
forward.y = 0f;
forward.Normalize();
Vector3 right = cam.right;
right.y = 0f;
right.Normalize();

Vector3 move = forward * Input.GetAxisRaw("Vertical") + right * Input.GetAxisRaw("Horizontal");
if (move.magnitude > 1f) move.Normalize();   // движение по диагонали не быстрее
controller.Move(move * speed * Time.deltaTime);

Camera.main — это камера с тегом MainCamera. Оба направления считываются каждый кадр, поэтому управление остаётся правильным при повороте камеры. Одновременное нажатие вверх и вправо складывает два единичных вектора под прямым углом, и длина результата составляет примерно 1.41, поэтому перемещение нормализуется, если длина превышает 1.

challenge icon

Задание

Средне

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

  1. В Update() скопируй cam.forward и cam.right, установи y равным 0 и нормализуй их.
  2. dir — это forward, умноженный на необработанное значение оси "Vertical", плюс right, умноженный на "Horizontal"; нормализуй результат, если его длина больше 1.
  3. Если dir != Vector3.zero, установи transform.rotation = Quaternion.LookRotation(dir);. Создай move на основе dir * speed.

Нажми «Играть»: нажатие вверх перемещает игрока от камеры, в какую бы сторону она ни смотрела. Затем нажми «Проверить».

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

using UnityEngine;

public class Mover : MonoBehaviour
{
    public float speed = 4f;
    public float gravity = -15f;
    public Transform cam;

    CharacterController controller;
    float verticalSpeed;

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

    void Update()
    {
        if (controller.isGrounded && verticalSpeed < 0f)
        {
            verticalSpeed = -2f;
        }
        verticalSpeed += gravity * Time.deltaTime;

        // Движется вдоль мировых осей: сделайте так, чтобы движение было относительно cam, а персонаж поворачивался в направлении движения
        Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
        move.y = verticalSpeed;
        controller.Move(move * Time.deltaTime);
    }
}

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

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