オイラー(Euler)回転の弱点:ジンバルロック ここまで学んできた回転方法は「オイラー」(Euler)回転といい、x, y, zの各軸ごとに別々に回転することにより、オブジェクトに連続に適用すると、自由に回転できる… 設定しても、回転順番を決めないといけない。X→Y→Z / Y→Z→X / X→Z→Y などの様々な組み合わせがあり、それぞれの最終結果がことなるので、混乱する可能性がある。  また、「ジンバルロック」という問題もある。次の装置を見てください。この装置は「X(赤)→  Y(緑)→  Z(青)」の順番で回転する装置。この状態で、物体が各軸の周りの回転を自由にできる。 X 軸の周り Y 軸の周り Z 軸の周り  ここで、Y軸の周りを90度回転してみると2つの回転軸が重なってしまうこの状態は「ジンバルロック」といい、1つの回転自由度が失ってしまった: 重なったXとZを回転しても、同じ回転になってしまう。 矢印の方向に回転したくても、できない  この場合はうまく回転できなくなるので、何かの解決を実装しないといけない。 一時的な解決:Angle-Axis(度-軸)回転  ジンバルロックになってしまった場合、一時的に新しい回転軸を作成し、その「仮想軸」の周りに回転ができる。この方法を使うと、定番のXYZだけではなく、お好みのベクトルの周りに回転ができる。  式は、今までの回転と同じアイデアである。sinとcosを使うが、回転する面はあるベクトル「 v 」を直交する  この場合は、回転行列は以下のようになる: ここで、 θ は回転角度で、   v は回転軸になる任意の3D単位ベクトルである これは今までの回転行列の一般な形である。例えば、回転軸は Z にすると: とすると、行列を更新すると: でも、 、なので… これで、Z 軸周りの回転行列に戻った! Unityのサポート Unityでは「 Quaternion.AngleAxis 」を使用し、任意の軸周りの回転ができる: // 以下、X 軸周りに45度を回転する相当: Vector3 axis = new Vector3(1, 0, 0); // 軸 float angle = 45; // 角度 transform.localRotation = Quaternion.AngleAxis(angle, axis); // 度・軸の回転 練習 惑星と月を真似しましょう。月が惑星の軸周りを従って回転させましょう: Moonスクリプトを作成し、 回転速度 追跡する惑星 惑星から離れる距離 Inspectorで設定できるようにする Quaternion.AngleAxis を使用し、惑星の「上向きベクトル」( transform.up ) の周りに回転する 実行し、Sceneビューで惑星を傾いて、回転を確認する。 汎用的な解決 Quaternion(クォータニオン - 四元数) 「クォータニオン」は、回転を表す4次元の数値である。一般な形は ここでは、「+」は加算ではなく、次元を表してる。ベクトルの表現にすると:  と等しいのである。4次元の数値であるため演算は多少ややこしいので、ゲームで使う目的だけに注目しましょう。   単位クォータニオン の特徴は: ジンバルロックせず、どの回転でも表現ができる 2つのクォータニオンを乗算は、2つの回転を連続に適用すると同じものである 逆クォータニオン(共役)は、逆回転と同じである クォータニオン⇔回転行列の変換ができる  クォータニオンがゲームの中で回転でよく使われるので、Unityがすでに実装されている。Unityは「 Quaternion 」というクラスがあり、すべての回転は「 Quaternion 」で行う。そもそも「 transform.rotation 」のデータ型は「 Quaternion 」だ! // Unityの中で、すべての回転は「Quaternion型」である Quaternion rot = transform.rotation; オイラー角度と Quaternion の変換 Unityではオイラー角度(XYZ回転)と Quaternion の変換メソッドが実装されている: // 回転を Quaternion として表現されている Quaternion rotA = transform.rotation; // オイラー角度を知りたいなら: Vector3 angles = rot.eulerAngles; // 逆に、オイラー角度から Quaternion にしたいなら: Quaternion rotB = Quaternion.Euler(x, y, z); // x, y, z は各軸の回転である // このまま回転として利用できる transform.rotation = rotB; 掛け算(乗算) クォータニオンが重要なので簡単にクォータニオンの掛け算を理解していきましょう。なお、式を覚えるよりも、掛け算はどのような影響があるのかを覚えてください。 2つのクォータニオン「q」と「p」があり、それぞれは別の回転であるとしたら「p × q」は、連続に2つの回転を適用したことと同じである。 クォータニオン「p」による回転 クォータニオン「p」による回転 クォータニオン「q」による回転 q × p の結果 式は教科書にある(泣きたくなるぐらい大変)が、Unity の Quaternion なら「*」で計算できる: // 「p」と「q」それぞれは「Quaternion」である Quaternion qp = q * p;  注意:クォータニオンの積は可換でない。回転の順番により、最後の結果が変わるので、行列と同様に: q × p p × q 回転行列との関係 任意の単位クォータニオンを今まで勉強してきた回転行列として表現ができるので、他の変換と組み合わせることができる。 「a, b, c, d」はクォータニオンの成分である。これで、 クォータニオンを回転行列に変換でき、他の変換(移動、拡大縮小)との連結できるようになる。