【Unity】2つのベクトル間の角度を求める

こじゃらこじゃら

次のようなベクトル同士がなす角度を求めるにはどうすればいいの~?

このはこのは

Unityの角度取得メソッドを使えば求められるわ!
角度の計算方法にはいくつか種類があるの。

与えられた2つのベクトルのなす角度を求めたい場合、Vector3.Angle()Vector3.SignedAngle()などの角度取得メソッドを使えば簡単に得ることができます。

var angle = Vector3.Angle(a, b);
var signedAngle = Vector3.SignedAngle(a, b, Vector3.up);

メソッドの挙動にはそれぞれ特徴があり、使用する際に挙動を把握しておくと安心です。

本記事では、2つのベクトルのなす角を求める方法をメソッドの挙動とともに解説します。

UCL UCL

この作品はユニティちゃんライセンス条項の元に提供されています

スポンサーリンク

ベクトル間の角度を求める

純粋に2つのベクトルとのなす角を知りたい場合、Unity標準メソッドVector3.Angle()メソッドを用いて求めることができます。

メソッドの形式は次の通りです。

public static float Angle(Vector3 from, Vector3 to);

fromtoには、なす角を求めたい2つのベクトルを指定します。
戻り値は、ベクトルfromとtoのなす角です。0°~180°の範囲の角度となります。

参考:Vector3-Angle – Unity スクリプトリファレンス

内部の計算式を知りたい方は、以下記事もご参考にしてください。

こじゃらこじゃら

例えば、自分の視点から見てベクトルがどっちに傾いているか知りたいときはどうすればいいの~?

このはこのは

Vector3.SignedAngle()メソッドが使えるわ!

向きを含んだベクトル間の角度を求める

あるベクトルから見て、もう一方のベクトルがどちらに傾いているかの情報を含めてベクトル間の角度を求めたい場合、Vector3.SignedAngle()メソッドを使います。

メソッドの形式は次の通りです。

public static float SignedAngle(Vector3 from, Vector3 to, Vector3 axis);

fromには基準となるベクトルtoにはもう一方のベクトルを指定します。
axisには、向きの基準を決める軸を指定します。

戻り値は、軸に対して左ねじ方向なら正、右ねじ方向なら負のなす角度です。

ここで注意すべき点は、角度の大きさはVector3.Angle()のリターン値になるところです。
平面に投影した角度ではありません。

参考:Vector3-SignedAngle – Unity スクリプトリファレンス

平面に投影したベクトル間の角度を求めるには、後述するメソッドを使います。

平面に投影したベクトル間の角度を求める

平面に投影した角度を求めるためには、指定された平面に投影してから角度を計算する必要があります。

平面の指定には、法線ベクトルを使います。
法線ベクトルとは、面に垂直なベクトルです。

平面に投影されたベクトルを取得するためには、Vector3.ProjectOnPlane()メソッドを使用します。

public static Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal);

vectorには、平面に投影させたいベクトルを指定します。
planeNormalには、投影面の法線ベクトルを指定します。

戻り値は、投影面に投影されたベクトルです。

参考:Vector3-ProjectOnPlane – Unity スクリプトリファレンス

計算式を知りたい方は、こちらの記事もご覧ください。

面に投影されたベクトル間の角度は、投影されたベクトル投影面の法線ベクトルをVector3.SignedAngle()に渡すことで、向きも含めて求めることができます。

例えば、床面に投影したベクトル同士の符号付き角度を求めるコードは次のようになります。

// 空間上のベクトル
var from = new Vector3(1, 2, 3);
var to = new Vector3(4, 5, 6);

// 平面の法線ベクトル(上向きベクトルとする)
var planeNormal = Vector3.up;

// 平面に投影されたベクトルを求める
var planeFrom = Vector3.ProjectOnPlane(from, planeNormal);
var planeTo = Vector3.ProjectOnPlane(to, planeNormal);

// 平面に投影されたベクトル同士の符号付き角度
// 時計回りで正、反時計回りで負
var signedAngle = Vector3.SignedAngle(planeFrom, planeTo, planeNormal);

例では、平面の法線ベクトルを真上にしているため、fromから見てtoが時計回りなら正、反時計回りなら負の角度が求まります。

さいごに

ベクトル間の角度が分かれば、ターゲットを追尾したり、ターゲットの方に向いたりと様々な動きに応用できます。

Unity提供のメソッドを用いることで、ベクトルの数式を自分で実装することなく角度を求めることができます。

ご参考にしていただければ幸いです。

関連記事

参考サイト

スポンサーリンク