Кватернионы
Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 43 из 71.
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 вылетали три пули веером, поворачивающиеся вместе с пушкой.
- Замени строку
Instantiateнаfor (int i = -1; i <= 1; i++). - Внутри цикла задай
Quaternion aim = transform.rotation * Quaternion.Euler(0, i * spread, 0);. - Создавай каждую пулю на расстоянии 1 единицы по направлению её движения:
Instantiate(bulletPrefab, transform.position + aim * Vector3.forward, aim);.
Нажми «Играть», поверни пушку и стреляй: три пули разлетятся веером с интервалом 20 градусов. Затем нажми «Проверить».
Попробуйте сами
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 для физикиСкоростьКинематические телаПовторение: пусковая площадка4Корутины
InvokeInvokeRepeating, CancelInvokeВаша первая корутинаЦиклы в корутинахОстановка корутинПовторение: обратный отсчёт10Проект: Побег с арены
АренаОхотники2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Монетная гонка
Катящийся шарСобираем монетыПотренируйтесь самостоятельно: Песочница Unity