Помогите разобраться с вращениями объектов и Quaternion.
Пытаюсь написать скрипт для управления стратегической камерой. Случился затык с поворотами, в результате чего хочу задать несколько вопросов.
Я поискал информацию про повороты объектов в Unity и нашел несколько способов управлением поворота объекта:
- Quaternion.Euler - когда мы передаем поворот в координатах Vector3
- Quaternion AngleAxis - когда передаем градусы и ось
- И дополнительные функции, вроде LookAt, Rotate и т.д.
Скрипт камеры устроен таким образом, что я храню позицию и наклон камеры в отдельных переменных, затем провожу с ними манипуляции, а затем применяю к объекту камеры. Поэтому использовать функции LookAt, Rotate и т.д. не хочется. В результате остановился на Euler и AngleAxis.
Моя камера располагается над картой под определенным углом. Ее параметры: Position: (0, 30, 0) Rotation: (60, 0, 0).
Следовательно вращать я ее хочу вдоль оси Y, но так, чтобы она всегда оставалась под углом 60 к земле.
Вопрос 1: В одной из найденных мною статей, я нашел информацию, что Euler дороже и лучше использовать AngleAxis, так ли это? Или разницы нет?
Вопрос 2: При реализации через Euler вроде все работает (код условный, без разделения на функции):
Синтаксис:
Используется csharp
private Vector3 rotation;
rotation = settings.Rotation.eulerAngles;
if (input.GetKey(KeyKode.E)) speed = horizontalSpeed * Time.deltaTime;
rotation.y += speed;
settings.Rotation = Quaternion.Euler(rotation);
rotation = settings.Rotation.eulerAngles;
if (input.GetKey(KeyKode.E)) speed = horizontalSpeed * Time.deltaTime;
rotation.y += speed;
settings.Rotation = Quaternion.Euler(rotation);
В такой реализации камера вращается вокруг глобальной оси Y и сохраняет свой наклон.
Прочитав информацию из вопроса 1, я попытался переделать все на AngleAxis и тут мне не понятен принцип его работы.
Я так понимаю, мы задаем ось вращения и угол поворота вокруг этой оси. Но написанный мною код работает не так, как я ожидаю:
Синтаксис:
Используется csharp
private Quaternion horizontalRotation;
private Quaternion verticalRotation;
if (input.GetKey(KeyKode.E)) speed = horizontalSpeed * Time.deltaTime;
horizontalRotation = Quaternion.AngleAxis(speed, Vector3.up);
settings.Rotation *= horizontalRotation * verticalRotation;
private Quaternion verticalRotation;
if (input.GetKey(KeyKode.E)) speed = horizontalSpeed * Time.deltaTime;
horizontalRotation = Quaternion.AngleAxis(speed, Vector3.up);
settings.Rotation *= horizontalRotation * verticalRotation;
В результате выполнения этого кода, камера вращается вправо влево, а не вокруг оси Y. Я так понимаю, что ось задалась локальная, хотя не понимаю почему, ведь Vector3.up это глобальная координата. Как тогда задать эту ось в глобальных координатах?