クォータニオン
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 41/63。
Quaternionは回転を表すUnityの型です。transform.rotationもその一つであり、Quaternion.Eulerが返す値も同様です。4つの数値x、y、z、wは角度ではなく、自分で設定する必要はありません。回転を使うときは乗算します。回転にベクトルを掛けると、そのベクトルの向きが変わります。
Vector3 a = Quaternion.Euler(0, 90, 0) * Vector3.forward; // (1, 0, 0)
Vector3 b = Quaternion.Euler(0, 0, 45) * new Vector3(2, 0, 0); // (1.41, 1.41, 0)
Vector3 lamp = transform.position + transform.rotation * new Vector3(0, 1, 2);回転は左側に置きます。Vector3.forward * transform.rotationはコンパイルできません。3行目では、オフセットをオブジェクト自身の回転に合わせて回転させています。そのため、lampはオブジェクトがどちらを向いていても、オブジェクト自身の方向を基準に、1単位上、2単位前の位置になります。
回転に回転を掛けると、2つの回転が合成されます。transform.rotation * Quaternion.Euler(0, 90, 0)は、まずオブジェクトを回転させてから、その自身のy軸を中心に4分の1回転させます。順序を入れ替えると、4分の1回転はワールドのy軸を中心に行われます。直立したオブジェクトでは、どちらも同じ結果になります。30度傾いた飛行機では結果が異なります。飛行機自身のy軸も一緒に傾くためです。
Quaternion banked = Quaternion.Euler(0, 0, 30);
Quaternion own = banked * Quaternion.Euler(0, 90, 0); // 機首 (0.87, 0.5, 0): 旋回しながら上昇する
Quaternion world = Quaternion.Euler(0, 90, 0) * banked; // 機首 (1, 0, 0): 水平を保つQuaternion.identityはまったく回転していない状態で、Instantiateに渡したものです。これを掛けても何も変わらず、transform.rotation = Quaternion.identity;とすると、オブジェクトは回転していない姿勢に戻ります。
チャレンジ
中級銃は左右の矢印キーで回転し、Spaceキーを押すと正面に弾を1発発射します。Spaceキーで弾を3発、扇状に発射するようにしてください。1発は正面に、1発は銃の向きから右にspread(20)度、もう1発は左に20度向けます。扇状の発射方向は銃と一緒に回転する必要があります。
- 各弾はそれぞれの方向を向きます(用意されているBulletスクリプトは、弾をその前方方向に飛ばします)。
- 各弾は、銃の中心からそれぞれの方向に沿って1単位離れた位置から発射されます。
Playを押して、回転させて発射し、次にCheckを押してください。
自分で試してみよう
using UnityEngine;
public class Gun : MonoBehaviour
{
public GameObject bulletPrefab;
public float turnSpeed = 90f;
public float spread = 20f;
void Update()
{
if (Input.GetKey(KeyCode.RightArrow)) transform.Rotate(0, turnSpeed * Time.deltaTime, 0);
if (Input.GetKey(KeyCode.LeftArrow)) transform.Rotate(0, -turnSpeed * Time.deltaTime, 0);
if (Input.GetKeyDown(KeyCode.Space))
{
// 弾を1発、正面に発射する。-spread度、0度、spread度の方向に3発発射する。
Instantiate(bulletPrefab, transform.position, transform.rotation);
}
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。