【Unity】オブジェクトの向きを取得する

ゲームオブジェクトがどこに向いているかを知りたい場合はどうすればいいの~?

Transformを調べれば分かるわ!
向きはベクトルとして得られるの。

Unityでは、オブジェクトの向きは、傾き(姿勢)から計算することができます。 [1]

しかしながら、オブジェクトのといった決まった向きは、Transformプロパティから向きベクトルとして簡単に取得できます。

本記事では、ゲームオブジェクトの向きをスクリプトから取得する方法をご紹介します。

正面の向きのベクトルを取得する

ゲームオブジェクトの正面の向きは、Transform.forwardフィールドから取得することができます。

var direction = transform.forward;

これは、シーンエディタで該当するオブジェクトを選択したときに表示されるz軸向き(青色)のベクトルに相当します。

Transform.forwardワールド座標系で表現された長さが1の単位ベクトルです。

X、Y軸向きのベクトルも同様に取得可能です。

右・上向きのベクトルを取得する

右向きはTransform.right上向きはTransform.upから取得できます。
Transform.rightはシーンエディタで該当オブジェクトを選択したときに表示されるx軸向き(赤色)のベクトル、Transform.upはy軸向き(緑色)のベクトルに相当します。

Transform.forwardと同じくワールド座標系におけるベクトルです。

例えば、後ろとかとか向きを求めたいときはどうするの?

ベクトルの符号反転を駆使すれば求められるわ!

後ろ・左・下向きのベクトルを取得する

今度はこれまでの応用です。

後ろ、左、下向きのベクトルは、それぞれ正面、右、上向きのベクトルの符号を反転させたベクトルとなります。

var back = -transform.forward;
var left = -transform.right;
var down = -transform.up;

サンプル

オブジェクトのリアルタイムな向きをデバッグログで表示するサンプルです。

スクリプト

CalcDirection.cs
using UnityEngine;

// オブジェクトの向きを取得する
public class CalcDirection : MonoBehaviour
{
    private Transform _transform;

    private void Start()
    {
        // transformに毎回アクセスすると重いので、キャッシュしておく
        _transform = transform;
    }

    private void Update()
    {
        // 正面・右・上向き
        var forward = _transform.forward;
        var right = _transform.right;
        var up = _transform.up;

        // 後ろ・左・下向き
        var back = -forward;
        var left = -right;
        var down = -up;

        // ログ表示
        Debug.Log($"正面:{forward}, 右:{right}, 上:{up}, 後ろ{back}, 左{left}, 下{down}");
    }
}

実行結果

ローカル座標系における向きについて

これまでご紹介した向きはすべてワールド座標系でしたが、ローカル座標系の場合は値が常に固定です。
transform.~ではなく、Vector3.~にコードを置き換えれば良いです。

また、後ろ、左、下向きのベクトルは、それぞれVector3.back、Vector3.left、Vector3.downプロパティとして参照できます。

// 正面・右・上向き
var forward = Vector3.forward;
var right = Vector3.right;
var up = Vector3.up;

// 後ろ・左・下向き
var back = Vector3.back;
var left = Vector3.left;
var down = Vector3.down;

斜め向きのベクトルを取得する

正面や右、上などの決まった向きなら、Transformプロパティから簡単に取得できることが分かりました。しかし、右前や斜め上など任意の向きを取得したい場合、別の方法で取得する必要があります。

次に紹介する二種類の取得方法があります。

Transform.rotationを用いる

オブジェクトの姿勢はTransform.rotationで表現されています。
Transform.rotationはワールド空間において、どの軸周りにどの角度だけ回転したかを表すクォータニオンです。

ローカル空間における向きベクトルにTransform.rotationを掛けることで、ワールド空間における向きを算出できます。

例えば、オブジェクトの右前を取得するコードは次のようになります。

var rightForward = transform.rotation * new Vector3(1, 0, 1).normalized;

Transform.TransformDirection()メソッドを用いる

ローカル空間の向きベクトルは、Transform.TransformDirection()メソッドを用いてワールド空間に変換できます。

変換処理は次のようになります。

var rightForward = transform.TransformDirection(new Vector3(1, 0, 1).normalized);

三種類の取得方法の結果比較

これまで紹介したオブジェクトの向きの取得方法は、求める過程が異なりますが、結果は同じになるはずです。

正面方向の取得を例にとって結果を確認してみましょう。

スクリプト

DirectionComparison.cs
using UnityEngine;

public class DirectionComparison : MonoBehaviour
{
    private Transform _transform;

    private void Start()
    {
        _transform = transform;
    }

    private void Update()
    {
        // Transform.forwardより向きを取得
        var forward = _transform.forward;
        
        // Vector3.forwardに姿勢のクォータニオンを掛ける
        var forward2 = _transform.rotation * Vector3.forward;
        
        // Vector3.forwardをローカル座標系からワールド座標系に変換
        var forward3 = _transform.TransformDirection(Vector3.forward);
        
        Debug.Log($"1:{forward}, 2:{forward2}, 3:{forward3}");
    }
}

実行結果

全ての結果が一致していることが確認できました!

さいごに

ワールド座標系におけるオブジェクトの向きはTransform.rotationを用いて算出することも可能ですが、正面や右向きなど決まった向きなら簡単に調べることが可能です。

向きベクトルはクォータニオンと並んで回転を扱うのに役立ちます。
是非活用してみてください!

参考サイト