Version: 2019.3
言語: 日本語
Scale Constraint
ライト

Unity の回転と向き

3D アプリケーションの回転は、たいていクォータ二オンかオイラー角のどちらかによって表されています。それぞれ、利点と欠点があります。Unity では内部でクォータ二オンを採用していますが、編集しやすいように、Inspector では同等のオイラー角で表しています。

オイラー角とクオータニオン

オイラー角

Euler angles are represented by three angle values for X, Y and Z that are applied sequentially. To apply a Euler rotation to a particular GameObject, each rotation value is applied in turn, as a rotation around its corresponding axis.

  • 利点 - オイラー角は、3 つの角度から構成される直感的で「人間が理解できる」フォーマットで表現されています。
  • 利点 - オイラー角は、180 度以上の回転を経て、1 つの向きから別の向きへの回転を表現できます。
  • 制限 - オイラー角は ジンバルロック (Gimbal lock) として知られている制限があります。対象をそれぞれの軸で順に回転させるとき、1 番目か 2 番目の回転によって、結果的に 3 つ目の軸の方向が以前の 2 つの軸の方向のいずれかとそろってしまうことがあります。つまり、3 番目の回転値を 3つ目の軸を中心に反映できないために「角度の自由」が失われてしまいます。

クォータ二オン

クォータニオンは、オブジェクトの向きや回転を表すのに使用されます。この表現法では、内部で 4 つの数字 (Unity では x、y、z、w と呼びます) で構成されています。ただし、この数字は、角度や軸を表現しているわけでなく、通常、直接アクセスすることはありません。クォータ二オン (四元数) について特別に興味がない限り、クォータニオンが 3D 空間の回転を表しているのだということを知っているだけで十分で、通常、x、y、z プロパティを操作したり変更することはありません。

ベクトルが位置と方向 (方向は原点から測ります) を表現するのと同様に、クォータ二オンは向きと回転を表現できます。回転は、回転「基準」か「単位」を基準に測られます。回転を、ある向きからもう一方の向きへの方向として計測するため、クォータ二オンでは、180 度より大きな回転を表現することができません。

  • 利点 - クォータ二オンの回転は、ジンバルロックの影響を受けません。
  • 制限 - 単体のクォータ二オンでは、180 度を超す回転を表すことができません。
  • 制限 - クォータ二オンの数的表現は、直感的に理解できません。

Unity では、ゲームオブジェクトのすべての回転は、内部ではクォータ二オンで保存します。なぜなら、利点のほうが、制限を上回るためです。

Transform Inspector では、オイラー角を使って rotation (回転) を表示します。なぜなら、この方が理解しやすく、編集しやすいからです。Unityは、ゲームオブジェクトの回転のために Inspector に入力された新しい値を、ゲームオブジェクトの新しいクォータ二オンの回転値に変換します。

ゲームオブジェクトの回転は、Inspector 内ではオイラー角で示され、編集されます。しかし、内部では、クォータニオンで保存されています。
ゲームオブジェクトの回転は、Inspector 内ではオイラー角で示され、編集されます。しかし、内部では、クォータニオンで保存されています。

この影響で、Inspector に X: 0, Y: 365, Z: 0 ゲームオブジェクトの回転値の入力が可能になります。このような値はクォータニオンでは表せないため、再生モードで、ゲームオブジェクトの回転値は X: 0, Y: 5, Z: 0 に変わります。これは「360度のフル回転プラス 5 度」という概念のないクォータニオンに回転値が変換されたため、値は、回転が同じ方向になるように、単純に置き換えられたものです。

Implications for scripting

スクリプトで回転を扱うとき、Quaternion クラスとその関数を使用し、回転値を作成、変更します。ある状況では、オイラー角の使用が有効な場合もあります。ただし、以下を注意する必要があります。 - オイラー角を扱える Quaternion クラス関数を使用してください。 - 回転からオイラー角を取得、変更、再適用することは、意図しない作用の原因になることがあります。

Creating and manipulating quaternions directly

Unity の Quaternion クラスには、多くの関数が備わっており、オイラー角をまったく使用しないで回転を作成し、操作することができます。以下は、その例です。

作成

操作

However sometimes it’s desirable to use Euler angles in your scripts. In this case it’s important to note that you must keep your angles in variables, and only use them to apply them as Euler angles to your rotation. While it’s possible to retrieve Euler angles from a quaternion, if you retrieve, modify and re-apply, problems are likely to arise.

ここで、一般的によくある 誤り を、ゲームオブジェクトを X 軸の周りで 1 秒につき 10 度回転させようろする例を使用して紹介します。以下は 行うべきでない 事例です。

// rotation scripting mistake #1
// the mistake here is that we are modifying the x value of a quaternion
// this value does not represent an angle, and does not produce desired results
    
void Update () 
    {
    var rot = transform.rotation;
    rot.x += Time.deltaTime * 10;
    transform.rotation = rot;
        
    }
// rotation scripting mistake #2
// Read, modify, then write the Euler values from a Quaternion.
// Because these values are calculated from a Quaternion,
// each new rotation might return very different Euler angles, which might suffer from gimbal lock.
        
void Update () 
    {
        var angles = transform.rotation.eulerAngles;
        angles.x += Time.deltaTime * 10;
        transform.rotation = Quaternion.Euler(angles);
    }

以下は、スクリプトでオイラー角を使う時の 正しい 使用法です。

// Rotation scripting with Euler angles correctly.
// Store the Euler angle in a class variable, and only use it to
// apply it as a Euler angle, but never rely on reading the Euler back.
        
float x;
void Update () 
    {
        x += Time.deltaTime * 10;
        transform.rotation = Quaternion.Euler(x,0,0);
    }

See documentation on Quaternion.Euler for more details.

アニメーションの影響

Unity 内部の Animation ウィンドウ を含め、多くの 3D オーサリングパッケージでは、アニメーションの間に、オイラー角で回転を指定することができます。

このような回転値は、しばしば、クォータニオンで表現できる範囲を超越することがあります。例えば、ゲームオブジェクトがその場で 720 度回転する場合、オイラー角では X: 0, Y: 720, Z:0 と示します。しかし、これは、実際にクォータニオンで表現できる値ではありません。

Unity のアニメーションウィンドウ

Unity のアニメーションウィンドウ内で、どのように回転を補間するか ( クォータニオンとオイラー角どちらを使用するか ) を指定できるオプションがあります。オイラー角での補間を指定すると、Unity は角度で指定されたすべての範囲を含む動きを可能にします。一方、クォータニオン回転では、単に特定の向きを向かせることが目的なので、Unity は、クォータニオン補間で最短距離を通って回転させます。詳しい情報は、アニメーションカーブを使用するを参照してください。

外部アニメーションソース

アニメーションを外部ソースからインポートする場合、これらのファイルは、通常はオイラー形式の回転キーフレームアニメーションを含んでいます。Unity のデフォルトのビヘイビアでは、これらのアニメーションをリサンプルして、各フレームごとに新しくクォータニオンキーフレームを生成し、キーフレーム間の回転がクォータニオンの有効範囲を超える状況をすべて回避しようとします。

例えば、6 フレーム離れた 2 つのキーフレーム (最初のフレームの X 値が 0、 2 番目のフレームの X 値が 270) があるとします。リサンプリングしないと、クォータニオン補間では、この 2 つのキーフレームを 90 度逆方向に回転させます。なぜなら、これが、最初の向きから2番目の向きにするための最短の方法だからです。しかし、リサンプリングして各フレームにキーフレームを加えると、今度はキーフレーム間では 45 度しかないので、正しく回転します。

リサンプリングを行っても、インポートしたアニメーションのクォータニオン表示がオリジナルに十分近い値にならない場合があります。このため、Unity 5.3 以降では、アニメーションリサンプリングをオフにするオプションがあります。これを使うと、代わりに、ランタイムにオイラーアニメーションキーフレームを使用します。詳しい情報は、Animation Import of Euler Curve Rotations を参照してください。

Scale Constraint
ライト