強火で進め

このブログではプログラム関連の記事を中心に書いてます。

Quaternion.Slerp() についての解説


今回のサンプルはこちらで試せます。ソースファイルはこちら

プログラムはこの様に成ります。

【Test.js】

var startFlag : boolean;

function Update () {
	if (startFlag) {
		var toRot : Quaternion = Quaternion.Euler(0, 90, 0);
		transform.rotation = Quaternion.Slerp (transform.rotation, toRot, Time.deltaTime * 0.5);
	}
}

function OnGUI () {
	var fromRot;
	var toRot;
	if (GUI.Button (Rect(5, 5, 150, 40), "回転(1)")) {
		startFlag = true;
	}
	if (GUI.Button (Rect(5, 50, 150, 40), "回転(2)")) {
		fromRot = Quaternion.Euler(0, 0, 0);
		toRot = Quaternion.Euler(0, 90, 0);
		transform.rotation = Quaternion.Slerp (fromRot, toRot, 0.5);
	}
	if (GUI.Button (Rect(5, 95, 150, 40), "回転(3)")) {
		toRot = Quaternion.Euler(0, 90, 0);
		transform.rotation = Quaternion.Slerp (transform.rotation, toRot, 0.5);
	}
	if (GUI.Button (Rect(5, 140, 150, 40), "回転をリセット")) {
		startFlag = false;
		transform.rotation = Quaternion.Euler(0, 0, 0);
	}
	GUI.Label (Rect(5, Screen.height-20, 150, 20), "Rotation.Y = "+transform.rotation.eulerAngles.y);
}

ステージにCubeを配置し、このプログラムを追加しています。

動作確認

まずは「回転(1)」ボタンを押してみて下さい。

するとCubeの Rotation.Y の値(画面左下に表示)が徐々に90に近づいて行く事が確認できるかと思います。また、値が90に近づくほど回転量が減って行く事を確認して下さい。
※一度、「回転をリセット」ボタンを押してからもう一度押すと再度確認出来ます。

次に一度、「回転をリセット」ボタンを押してから「回転(2)」ボタンを押してみて下さい。 Rotation.Y の値が45に成ったはずです。

次にもう一度、「回転をリセット」ボタンを押してから「回転(3)」ボタンを押してみて下さい。 Rotation.Y の値を確認しながら何度かボタンを押してみて下さい。

プログラムの解説

さて、動作の確認が終ったのでプログラムの解説に進みます。

まずは「回転(1)」ボタンの動作。このボタンを押すと startFlag がtrueになり、Update () の以下の処理が実行されます。

function Update () {
	if (startFlag) {
		var toRot : Quaternion = Quaternion.Euler(0, 90, 0);
		transform.rotation = Quaternion.Slerp (transform.rotation, toRot, Time.deltaTime * 0.5);
	}
}

ここで Quaternion.Slerp () が登場します。

Unity Script Reference – Quaternion.Slerp
http://unity3d.com/support/documentation/ScriptReference/Quaternion.Slerp.html

このメソッドの引数は(from=変更前のQuaternionの値, to=変更後のQuaternionの値, t=定数t)と成っています。

Quaternionは日本語では四元数と言い、3次元空間での回転を表現する事が可能です。詳しくは「クォータニオン」か「四元数」で検索してみて下さい。

Quaternion.Slerp () は「変更前のQuaternionの値」から「変更後のQuaternionの値」へ「定数t」で指定した量だけ近づける。という動作を行います。

定数tは0〜1の範囲で指定でき、それぞれの値の時に以下の様なQuaternionの値が返されます。

  • 0の時 → 「変更前のQuaternionの値」
  • 1の時 → 「変更後のQuaternionの値」
  • 0〜1の中間の値 → 「変更前のQuaternionの値」と「変更後のQuaternionの値」の中間の値

定数tについては「回転(2)」ボタンのプログラムを見ると良く分かるかと思います。これを実行した時はfromには Rotation.Y=0 、toには Rotation.Y=90 を指定しています。この状態で定数tは0.5、つまり丁度真ん中を指定している為、結果として Rotation.Y=45 と成ります。

	if (GUI.Button (Rect(5, 50, 150, 40), "回転(2)")) {
		fromRot = Quaternion.Euler(0, 0, 0);
		toRot = Quaternion.Euler(0, 90, 0);
		transform.rotation = Quaternion.Slerp (fromRot, toRot, 0.5);
	}

最後に「回転(3)」ボタン。こちらは「回転(2)」とはfromがtransform.rotationという違いしか有りません。

	if (GUI.Button (Rect(5, 95, 150, 40), "回転(3)")) {
		toRot = Quaternion.Euler(0, 90, 0);
		transform.rotation = Quaternion.Slerp (transform.rotation, toRot, 0.5);
	}

fromが現在のCubeの回転量に成っているため最初は 0→90 の中間なので 45 。もう一度押すと 45→90 の間なので 67.5 。次は 78.75 と、徐々に回転量が少なく(半分づつに)なって行きます。

このボタンを押す動作が自動的に行われていたのが「回転(1)」ボタンを押した時の処理です。

なお、Slerpは何かな?と思い調べてみた所

SlerpはSphercal Linear Interpolationの略で、日本語では球面線形補間となります。

との事でした。

クォータニオンの使いどころ - ひにけにXNA - Site Home - MSDN Blogs
http://blogs.msdn.com/b/ito/archive/2009/05/01/more-bones-04.aspx