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

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

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

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

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

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

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

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

動作環境
  • Unity2022.2.3f1

ベクトルの正規化とは

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

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

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

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

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

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

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

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

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

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

使用例

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

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}");
    }
}

実行結果

さいごに

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

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

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

参考サイト