Ответы:
Вы можете разложить кватернион на набор углов отклонения / рыскания / крена, но обычно это излишне.
Вместо того, чтобы составлять свои кватернионы, как это:
cameraOrientation = cameraOrientation * framePitch * frameYaw;
Попробуй это:
cameraOrientation = framePitch * cameraOrientation * frameYaw;
Тогда он никогда не будет генерировать наклон / крен и эквивалентен хранению рыскания и тангажа отдельно
framePitch
и frameYaw
float
типы? Кроме того, я был бы признателен за разъяснения по поводу вашего первого предложения.
cameraOrientation
, framePitch
и frameYaw
все кватернионы (каждый кватернион равен 4 числам с плавающей запятой или двойным числам ).
Это проблема, которая у меня возникла некоторое время, и я не мог найти ответы на нее, поэтому я решил опубликовать ее здесь.
Это на самом деле довольно просто. То, как вы, скорее всего, делаете повороты, выглядит так:
currentDirection * newRotation;
Но делать это так же не получается.
newRotation * currentDirection;
То, что вам нужно сделать, это сделать это в первом порядке для вращений вверх и вниз и во втором порядке для боковых вращений.
Для меня это было так:
if (keyboard.IsKeyDown(Keys.Up))
Direction = Direction * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), TurnSpeed);
if (keyboard.IsKeyDown(Keys.Down))
Direction = Direction * Quaternion.CreateFromAxisAngle(new Vector3(-1, 0, 0), TurnSpeed);
if (keyboard.IsKeyDown(Keys.Left))
Direction = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), TurnSpeed) * Direction;
if (keyboard.IsKeyDown(Keys.Right))
Direction = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, -1), TurnSpeed) * Direction;
По какой-то причине первый способ имеет вращение относительно текущего бокового направления, которое требуется для перемещения вверх и вниз, но вы не хотите этого для боковых вращений, поэтому необходим второй порядок.
Для камеры FPS вы обычно не хотите вращаться и ограничены с шагом +/- 90 градусов, поэтому я бы просто отслеживал текущее состояние, используя углы поворота и рыскания. Полная сила кватернионов не очень полезна для этого.
Вы все еще можете конвертировать углы рыскания / тангажа в кватернионы и из них в случае, если вы хотите переключиться между камерой FPS и анимированными камерами, используя кватернионную интерполяцию ключевых кадров или что-то в этом роде.
Другой простой трюк - поместить камеру в объект GameObject и заставить вращение Yaw управлять игровым объектом, в то время как дочерняя камера настроена с помощью координат высоты тона:
playerCameraHolder.transform.Rotate(0, rotationYaw, 0);
playerCamera.transform.Rotate(rotationPitch, 0, 0);