【Unity】ベクトルを正規化する

こじゃらこじゃら

ベクトルの向きを変えずに大きさだけを1にする方法を教えてほしいの。

このはこのは

ベクトルを正規化すれば良いわ。Unityには正規化を簡単に行えるAPIが用意されているの。

Unityで登場するVector2Vector3型のベクトルを正規化する方法の紹介です。

正規化されたベクトルは、次のようにnormalizedプロパティから取得できます。

// 正規化ベクトルを取得
var normalizedVector2 = _vector2.normalized;
var normalizedVector3 = _vector3.normalized;

ただし、大きさがほぼ0のベクトルの正規化を行おうとした場合は、零ベクトル [1] になります。

また、Normalizeメソッドの実行でベクトル自身を直接正規化することも可能です。

Vector2 vec = new Vector2(1, 2, 3);

// ベクトルを正規化
vec.Normalize();

本記事では、これらのベクトルの正規化注意点について解説していきます。

動作環境
  • Unity 2021.2.3f1

スポンサーリンク

ベクトルの正規化とは

ベクトルの向きを維持したまま、長さを1にする計算のことを指します。

正規化ベクトルは、ベクトルをベクトルの大きさで割ることで求めることができます。

正規化の計算式
\vec{n} = \frac{\vec{v}}{|\vec{v}|}

\vec{v} : ベクトル
\vec{n} : 正規化ベクトル
|\vec{v}| \neq 0

そのため、大きさが0のベクトル(零ベクトル)を正規化しようとすると0除算エラーとなってしまいます。

後述するUnity APIでは、このようなベクトルが指定された場合は、零ベクトルを正規化ベクトルとして返すようにしています。

normalizedプロパティから正規化ベクトルを取得する

Vector2Vector3インスタンスの正規化ベクトルは、normalizedプロパティから取得できます。

正規化ベクトルを新しいインスタンスとして返します。読み取り専用プロパティのため、直接代入することはできません。

また、ベクトルの大きさがあまりにも小さい場合、零ベクトルを返します。 [2]

したがって、normalizedプロパティが返すベクトルは次式のようになります。

normalizeプロパティの計算式
\vec{n} = \left \{
\begin{array}{}

\dfrac{\vec{v}}{|\vec{v}|} & (|\vec{v}| > \varepsilon) \\
\\
\vec{0} & (|\vec{v}| \leq \varepsilon)

\end{array}
\right.

ただし、\varepsilon = 0.00001

使用例

インスペクターから設定されたベクトルを正規化してログ出力するサンプルスクリプトです。

NormalizeVectorExample.cs
using UnityEngine;

public class NormalizeVectorExample : MonoBehaviour
{
    [SerializeField] private Vector2 _vector2;
    [SerializeField] private Vector3 _vector3;

    private void Update()
    {
        // 正規化ベクトルを取得
        var normalizedVector2 = _vector2.normalized;
        var normalizedVector3 = _vector3.normalized;

        // 正規化ベクトルをログ出力
        print($"normalizedVector2 = {normalizedVector2}, normalizedVector3 = {normalizedVector3}");
    }
}

実行結果

Normalizeメソッドでベクトルを正規化する

Normalizeメソッドを使うと、ベクトルのインスタンス自身を長さ1で正規化することができます。

public void Normalize();

こちらもnormalizedプロパティ同様、ベクトルの長さが非常に小さい場合は零ベクトルとなります。

インスタンスをコピーする必要が無い場合はこちらを使用すると良いでしょう。

さいごに

ベクトルの正規化は、normalizedプロパティから正規化ベクトルを取得する形で行えます。

正規化の計算では、ベクトルによっては0除算エラーになってしまう可能性があるため、これらに対応する処理が必要になります。normalizedプロパティを使うと、この辺のエラー処理を内包してくれます。

正規化されたベクトルは、様々な計算で都合の良い性質があり、ベクトル関連のAPIでも内部的に活用されています。

関連記事

参考サイト

スポンサーリンク