エンジニア

Unityでベクトルを扱おう

投稿日:2015年5月15日 更新日:

今回の担当、大橋です。

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

採用情報

ワンダープラネットでは、一緒に働く仲間を幅広い職種で募集しております。

-エンジニア
-

© WonderPlanet Inc.