3D アプリケーションの回転は、たいていクォータ二オンかオイラー角のどちらかによって表されています。 それぞれ、利点と欠点があります。Unity では内部でクォータ二オンを採用していますが、編集しやすいように、インスペクターでは同等のオイラー角で表しています。
オイラー角は、3つの角度の値を X、Y、Z 軸に順に当てはめて回転を表す簡易な方法です。オイラー角をあるオブジェクトに応用する場合は、オブジェクトを各軸に沿って与えられた角度で回転させます。
クォータニオンは、オブジェクトの向きや回転を表すのに使用されます。この表現法では、内部で 4つの数字 (Unity では x、y、z、w と呼びます) で構成されています。ただし、この数字は、角度や軸を表現しているわけでなく、通常、直接アクセスすることはありません。クォータ二オン (四元数)について特別に興味がない限り、クォータニオンが 3D 空間の回転を表しているのだということを知っているだけで十分で、通常、x、y、z プロパティを操作したり変更することはありません。
ベクトルが位置と方向 (方向は原点から測ります) を表現するのと同様に、クォータ二オンは向きと回転を表現できます。回転は、回転「基準」か「単位」を基準に測られます。回転を、ある向きからもう一方の向きへの方向として計測するため、クォータ二オンでは、180度より大きな回転を表現することができません。
Unity では、ゲームオブジェクトのすべての回転は、内部ではクォータ二オンで保存します。なぜなら、利点のほうが、制限を上回るためです。
しかし、Transform Inspector では、回転は、理解しやすく編集しやすいオイラー角で表示されます。 ゲームオブジェクトを回転させるために Inspector に新しい値を入力すると、目に見えない内部で、新しいクォータニオン回転値に変換されます。
この影響で、Inspector に X: 0、Y: 365、Z: 0 といったゲームオブジェクトの回転値の入力が可能になります。このような値はクォータニオンでは表せないため、プレイするとき、オブジェクトの回転値は X: 0、Y: 5、Z: 0 (または、これに近い値) に変わります。これは「360度のフル回転プラス 5度」という概念のないクォータニオンに、回転値が変換されたためです。値は、回転が同じ方向になるように、単純に置き換えられたものです。
スクリプトで回転を扱うとき、Quaternion クラスとその関数を使用し、回転値を作成、変更します。ある状況では、オイラー角の使用が有効な場合もあります。ただし、以下の注意が必要です。 - オイラー角を扱える Quaternion クラス関数を使用してください。 - 回転からオイラー角を取得、変更、再適用することは、意図しない作用の原因になることがあります。
Unity の Quaternion クラスには、多くの関数が備わっており、オイラー角をまったく使用しないで回転を作成し、操作することができます。以下は、その例です。
作成
操作
ただし、スクリプトでオイラー角を使用したほうがよい場合があります。そのような場合は、角度を変数に代入し、オイラー角として回転に適用するためにだけ使用することが重要です。オイラー角をクォータニオンから取得することは可能ですが、取得、変更、再適用すると、問題が発生します。
ここで、一般的によくある誤りの例を、オブジェクトを X 軸の周りで 1秒につき 10度回転させようとする場合を例にとって紹介します。以下は誤った使用法です。
// 回転のスクリプト 誤り #1
// the mistake here is that we are modifying the x value of a quaternion
// この値は角度を表しません。そのため、期待通りの結果が得られません。
void Update () {
var rot = transform.rotation;
rot.x += Time.deltaTime * 10;
transform.rotation = rot;
}
// 回転のスクリプト 誤り #2
// ここの誤りはオイラー値をクオータニオンから読み込み、修正し、書き込んでいることです。
// これらの値をクオータニオンで計算しているため
// それぞれの新しい回転はまったく異なるオイラー角を返し、それにはジンバルロックの問題がある場合があります。
void Update () {
var angles = transform.rotation.eulerAngles;
angles.x += Time.deltaTime * 10;
transform.rotation = Quaternion.Euler(angles);
}
以下は、スクリプトでオイラー角を使う時の正しい使用法です。
// 正しくオイラー角を用いた回転スクリプト。
// ここでは、オイラー角をクラス変数として格納します。
//それをオイラー角として使用しますが、決してオイラー角として読み込みには使いません。
float x;
void Update () {
x += Time.deltaTime * 10;
transform.rotation = Quaternion.Euler(x,0,0);
}
Unity 内部のアニメーションウィンドウを含め、多くの 3D オーサリングパッケージでは、アニメーションの間に、オイラー角で回転を指定することができます。
このような回転値は、しばしば、クォータニオンで表現できる範囲を超越することがあります。例えば、オブジェクトがその場で 720度回転する場合、オイラー角では X: 0、Y: 720、Z:0 と示します。しかし、これは、実際にクォータニオンで表現できる値ではありません。
Unity のアニメーションウィンドウ内で、どのように回転を補間するか ( クォータニオンとオイラー角どちらを使用するか ) を指定できるオプションがあります。オイラー角での補間を指定すると、Unity は角度で指定されたすべての範囲を含む動きを可能にします。一方、クォータニオン回転では、単に特定の向きを向かせることが目的なので、Unity は、クォータニオン補間で最短距離を通って回転させます。詳しい情報は、アニメーションカーブを使用するを参照してください。
アニメーションを外部ソースからインポートする場合、これらのファイルは、通常はオイラー形式の回転キーフレームアニメーションを含んでいます。Unity のデフォルトのビヘイビアでは、これらのアニメーションをリサンプルして、各フレームごとに新しくクォータニオンキーフレームを生成し、キーフレーム間の回転がクォータニオンの有効範囲を超える状況をすべて回避しようとします。
例えば、6フレーム離れた 2つのキーフレーム ( 最初のフレームの X値が 0、 2番目のフレームの X値が270 ) があるとします。リサンプリングしないと、クォータニオン補間で、この 2つのキーフレームを逆方向に 90度回転させます。なぜなら、これが、最初の向きから2番目の向きにするための最短の方法だからです。しかし、リサンプリングして各フレームにキーフレームを加えると、今度はキーフレーム間に45度しかないので、正しく回転します。
リサンプリングを行っても、インポートしたアニメーションのクォータニオン表示がオリジナルに十分近い値にならない場合があります。このため、Unity 5.3 以降では、アニメーションリサンプリングをオフにするオプションがあります。これを使うと、代わりに、ランタイムにオイラーアニメーションキーフレームを使用します。詳しい情報は、Animation Import of Euler Curve Rotations を参照してください。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.