Кватернионы
Часть раздела Физика и игровой процесс путешествия по 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; возвращает объект в исходное положение без поворота.
Задание
СреднеПушка поворачивается стрелками влево и вправо, а клавиша 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);
}
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Физика и игровой процесс
1Твёрдое тело
Гравитация и массаТолкаем с помощью AddForceПрыжок с импульсомFixedUpdate для физикиСкоростьКинематические телаПовторение: пусковая площадка2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Погоня за монетами
Катящийся мячМонеты для сбора