Risposte:
Potresti scomporre il tuo quaternione in una serie di angoli di imbardata / beccheggio / rollio, ma di solito è eccessivo.
Invece di comporre i tuoi quaternioni in questo modo:
cameraOrientation = cameraOrientation * framePitch * frameYaw;
Prova questo:
cameraOrientation = framePitch * cameraOrientation * frameYaw;
Quindi non genererà mai inclinazione / rollio ed equivale a memorizzare separatamente imbardata e inclinazione
framePitch
e frameYaw
float
tipi? Inoltre, sarei grato per alcuni chiarimenti sulla tua prima frase.
cameraOrientation
, framePitch
e frameYaw
sono tutti quaternioni (ogni quaternione è composto da 4 float o doppi).
Questo è un problema che ho avuto per un po ', e non sono riuscito a trovare alcuna risposta, quindi ho pensato di pubblicarlo qui.
In realtà è abbastanza semplice. Il modo in cui molto probabilmente stai facendo le rotazioni è come questo:
currentDirection * newRotation;
Ma farlo in questo modo non funziona neanche.
newRotation * currentDirection;
Quello che devi fare è farlo nel primo ordine per le rotazioni su e giù e nel secondo ordine per le rotazioni laterali.
Per me è stato così:
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;
Per un motivo, il primo modo ha la rotazione relativa all'attuale direzione laterale, che si desidera per su e giù, ma che non si desidera per le rotazioni laterali, motivo per cui è necessario il secondo ordine.
Per una fotocamera FPS di solito non si desidera il rollio e sono limitati a un angolo di +/- 90 gradi, quindi terrei solo traccia dello stato corrente usando gli angoli di imbardata e di imbardata. Il pieno potere dei quaternioni non è davvero utile per questo.
È comunque possibile convertire gli angoli di imbardata / inclinazione da e verso i quaternioni nel caso in cui si desideri eseguire la transizione tra la videocamera FPS e le videocamere animate utilizzando l'interpolazione del fotogramma chiave quaternione o qualcosa del genere.
Un altro semplice trucco è quello di mettere la telecamera in un GameObject e far controllare la rotazione dell'imbardata all'oggetto del gioco, mentre la camera del bambino è configurata con le coordinate Pitch:
playerCameraHolder.transform.Rotate(0, rotationYaw, 0);
playerCamera.transform.Rotate(rotationPitch, 0, 0);