Réponses:
Vous pouvez décomposer votre quaternion en un ensemble d'angles de lacet / tangage / roulis, mais c'est généralement exagéré.
Au lieu de composer vos quaternions comme ceci:
cameraOrientation = cameraOrientation * framePitch * frameYaw;
Essaye ça:
cameraOrientation = framePitch * cameraOrientation * frameYaw;
Il ne générera alors jamais d'inclinaison / roulis et équivaut à stocker le lacet et le tangage séparément
framePitch
et frameYaw
float
types? Je vous serais également reconnaissant de bien vouloir clarifier votre première phrase.
cameraOrientation
, framePitch
et frameYaw
sont tous des quaternions (chaque quaternion est composé de 4 flotteurs ou doubles).
C'est un problème que j'ai eu pendant un certain temps, et je n'ai trouvé aucune réponse, j'ai donc pensé le poster ici.
C'est en fait assez simple. Voici comment vous effectuez le plus probablement les rotations:
currentDirection * newRotation;
Mais le faire comme ça ne marche pas non plus.
newRotation * currentDirection;
Ce que vous devez faire, c'est le faire dans le premier ordre pour les rotations vers le haut et vers le bas, et dans le second ordre pour les rotations latérales.
Pour moi, c'était comme ça:
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;
Pour une raison, la première façon a la rotation par rapport à la direction latérale actuelle, que vous voulez pour le haut et le bas, mais vous ne voulez pas cela pour les rotations latérales, c'est pourquoi le deuxième ordre est nécessaire.
Pour une caméra FPS, vous ne voulez généralement pas de roulis et vous êtes limité à +/- 90 degrés, donc je garderais simplement trace de l'état actuel en utilisant les angles de lacet et de tangage. La pleine puissance des quaternions n'est pas vraiment utile pour cela.
Vous pouvez toujours convertir les angles de lacet / tangage vers et depuis les quaternions au cas où vous souhaiteriez faire la transition entre la caméra FPS et les caméras animées en utilisant l'interpolation d'images clés quaternion, ou quelque chose comme ça.
Une autre astuce simple consiste à placer la caméra dans un GameObject et à faire en sorte que la rotation de lacet contrôle l'objet de jeu, tandis que la caméra enfant est configurée avec les coordonnées de hauteur:
playerCameraHolder.transform.Rotate(0, rotationYaw, 0);
playerCamera.transform.Rotate(rotationPitch, 0, 0);