Menu
CoddyTech

Кватернионы

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 41 из 63.

Quaternion — это тип Unity для поворота: transform.rotation — это поворот, как и значение, которое возвращает Quaternion.Euler. Его четыре числа x, y, z и w — не углы, и вам никогда не нужно задавать их самостоятельно. Повороты перемножают. Поворот, умноженный на вектор, поворачивает вектор:

Vector3 a = Quaternion.Euler(0, 90, 0) * Vector3.forward;       // (1, 0, 0)
Vector3 b = Quaternion.Euler(0, 0, 45) * new Vector3(2, 0, 0);  // (1.41, 1.41, 0)
Vector3 lamp = transform.position + transform.rotation * new Vector3(0, 1, 2);

Поворот должен стоять слева: Vector3.forward * transform.rotation не компилируется. В третьей строке смещение поворачивается на собственный поворот объекта, поэтому lamp — это точка на 1 единицу выше и на 2 единицы впереди объекта в его собственных направлениях, куда бы он ни был обращён.

Поворот, умноженный на поворот, объединяет два поворота. transform.rotation * Quaternion.Euler(0, 90, 0) — это поворот объекта, за которым следует поворот на четверть оборота вокруг его собственной оси y; если поменять множители местами, поворот на четверть оборота будет вокруг оси y мира. Для вертикального объекта оба варианта дают одинаковый результат. Для самолёта, накренённого на 30 градусов, результат будет разным, потому что его собственная ось y тоже наклоняется:

Quaternion banked = Quaternion.Euler(0, 0, 30);
Quaternion own = banked * Quaternion.Euler(0, 90, 0);    // нос (0.87, 0.5, 0): при повороте он поднимается
Quaternion world = Quaternion.Euler(0, 90, 0) * banked;  // нос (1, 0, 0): он остаётся на прежней высоте

Quaternion.identity означает отсутствие поворота — именно его вы передавали в Instantiate. Умножение на него ничего не меняет, а transform.rotation = Quaternion.identity; возвращает объект в исходное положение без поворота.

challenge icon

Задание

Средне

Пушка поворачивается стрелками влево и вправо, а клавиша Space выпускает одну пулю прямо вперёд. Сделай так, чтобы при нажатии Space выпускалось три пули веером: одна прямо вперёд, одна под углом spread (20) градусов вправо относительно направления пушки и одна на 20 градусов влево. Разброс должен поворачиваться вместе с пушкой.

  • Каждая пуля направлена в свою сторону (готовый скрипт Bullet перемещает её вперёд по направлению её собственного вектора forward).
  • Каждая пуля начинает движение на расстоянии 1 единицы от центра пушки, вдоль собственного направления.

Нажми Play, поверни пушку и стреляй, затем нажми Check.

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

using UnityEngine;

public class Gun : MonoBehaviour
{
    public GameObject bulletPrefab;
    public float turnSpeed = 90f;
    public float spread = 20f;

    void Update()
    {
        if (Input.GetKey(KeyCode.RightArrow)) transform.Rotate(0, turnSpeed * Time.deltaTime, 0);
        if (Input.GetKey(KeyCode.LeftArrow)) transform.Rotate(0, -turnSpeed * Time.deltaTime, 0);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            // Одна пуля летит прямо вперёд. Выпусти три: под углами -spread, 0 и spread градусов.
            Instantiate(bulletPrefab, transform.position, transform.rotation);
        }
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Физика и игровой процесс