今回の担当、大橋です。
Unityでのベクトル(Vector3)の扱い方をまとめてみました。
基礎的なことが中心になってます。
スクリプトはC#です。
ベクトルの作成
まずはベクトルの作成です。
引数にx、y、z各成分の値を指定して作成できます。
引数を省略すると、長さ0の(0, 0, 0)のベクトルになります。
// ベクトル(0, 0, 0) var vec1 = new Vector3 (); // ベクトル(1, 2, 3) var vec2 = new Vector3 (1f, 2f, 3f);
ベクトルの足し算、引き算
ベクトルも足し算と引き算が出来ます。
2つのベクトルの各成分同士がそれぞれ加算、減算されます。
var vec1 = new Vector3 (1f, 2f, 3f); var vec2 = new Vector3 (1f, -1f, 2f); // 足し算 var res1 = vec1 + vec2; Debug.Log (res1.ToString ()); // 引き算 var res2 = vec1 - vec2; Debug.Log (res2.ToString ());
結果
res1:(2.0, 1.0, 5.0) res2:(0.0, 3.0, 1.0)
ベクトルの長さを取得
ベクトルには「長さ」の概念があります。
長さはmagnitudeで取得できます。
var vec1 = new Vector3 (1f, 2f, 3f); float len = vec1.magnitude; Debug.Log ("len:" + len);
結果
len:3.741657
ベクトルの長さを比較
複数のベクトルのVector3.magnitudeを比較することで、ベクトルの長さを比較できますが、
magnitudeの代わりにsqrMagnitudeを使った方が高速です。
ベクトルの長さを求める計算式には平方根(ルート)が含まれていますが、
sqrMagnitudeは平方根を求める前の値を取得できます。
平方根は比較的重い処理なので、平方根を求める前の値で比較した方が高速というわけです。
長さの大小の比較であれば、平方根を求める前の値でも問題ありません。
ただし、sqrMagnitudeの差が、そのまま長さの差ではないので注意です。
var vec1 = new Vector3 (1f, 2f, 3f); var vec2 = new Vector3 (1f, 1f, 2f); // magnitudで比較 bool res1 = vec1.magnitude > vec2.magnitude; Debug.Log ("res1:" + res1); // sqrMagnitudeで比較(こちらの方が高速) bool res2 = vec1.sqrMagnitude > vec2.sqrMagnitude; Debug.Log ("res2:" + res2);
結果
res1:True res2:True
ベクトルの長さを変える
ベクトルに対してfloat値を掛けたり、float値で割ったりすることで、
ベクトルの向きはそのままに、長さを変えることができます。
また、normalizedに対してfloat値を掛けることで、
ベクトルの長さがそのfloat値と同じになります。
normalizedは、そのベクトルの長さを1にしたベクトルです。
var vec1 = new Vector3 (1f, 2f, 3f); // 長さを2倍にする var res1 = vec1 * 2f; Debug.Log("res:" + res1 + ", len:" + vec1.magnitude + "->" + res1.magnitude); // 長さを1/2にする var res2 = vec1 / 2f; Debug.Log("res:" + res2 + ", len:" + vec1.magnitude + "->" + res2.magnitude); // 長さ5にする var res3 = vec1.normalized * 5; Debug.Log("res:" + res3 + ", len:" + vec1.magnitude + "->" + res3.magnitude);
結果
res:(1.3, 2.7, 4.0), len:3.741657->5 res:(1.3, 2.7, 4.0), len:3.741657->7.483315 res:(1.3, 2.7, 4.0), len:3.741657->1.870829
2つのベクトルの角度差を求める
Vector3.Angle関数で2つのベクトル間の角度を求めることができます。
これによって求められる角度は0〜180です。
var vec1 = new Vector3 (1f, 0f, 0f); var vec2 = new Vector3 (-1f, 1f, 0f); float angle = Vector3.Angle (vec1, vec2); Debug.Log ("angle:" + angle);
結果
angle:135
ベクトルを指定角度だけ回転させる
Quaternionをベクトルに掛けることで、ベクトルを回転させることができます。
回転の方向は、回転軸の向きに対してネジを締めるのとは逆方向に回転します。
var vec = new Vector3 (1f, 0f, 0f); // Y軸周りに45度だけ回転 var res1 = Quaternion.Euler (0f, 45f, 0f) * vec; Debug.Log ("res1:" + res1);
結果
res1:(0.7, 0.0, -0.7)
ベクトルを別のベクトルに向かって指定角度だけ回転させる
2つのベクトルがあり、一方のベクトルを、もう一方のベクトルに向かって指定角度だけ回転させたい場合、次のようなプログラムになります。
まず、Vector3.Crossで2つのベクトルに直交するベクトルを求め、
そのベクトルを軸にして、回転させたいベクトルを指定角度だけ回転させます。
var vec1 = new Vector3 (0f, 1f, 0f); var vec2 = new Vector3 (1f, 0f, 0f); // vec2をvec1に向かって30度回転させる var axis = Vector3.Cross (vec2, vec1); var res = Quaternion.AngleAxis (30f, axis) * vec2; Debug.Log ("res:" + res + ", angle:" + Vector3.Angle(vec1, vec2) + " -> " + Vector3.Angle(vec1, res));
結果
res:(0.9, 0.5, 0.0), angle:90 -> 60