【Unity】Vector3を使った移動方法や長さを低負荷に取得する方法

投稿者: | 2018年11月29日

 

スポンサーリンク

 

 

フィア
今回は「Vector3」の使い方だよ
カレン
数学的には高校生の内容だけど、

使い方が分かれば何とかなると思うから頑張ってね

 

— YouTubeなら5分22秒で学べます ―

 いいね    チャンネル登録

 

目次

 

 

Vector3とは

Vector3とは日本語でベクトルのことで、「大きさ」と「方向」の成分を持っています。

詳しくは高校の数学の範囲になるのですが、Unityでは「位置」と「方向」を指定したいときに使うと考えればいいと思います。

ちなみに、Unityの単位では、1辺や1マスの長さが1mなので、移動距離やスケールには注意してください。

 

ベクトルの例

 

Vector3の準備

今回は「Test」スクリプトを作成し、赤色のSphereへアタッチします。また、原点(x, y, z) = (0, 0, 0)の目印に青色のCubeを設置しました。

 

 

Vector3で座標を指定してオブジェクトを設置する

 

 

Vector3 を使用するときは、「Vector3 a = new Vector3(x, y, z);」のように宣言します。

newを見てもわかるように、これはVector3 型のクラスをインスタンス化しています。

インスタンス化については難しく考える必要はありません。今は単純に、「使用可能にするための呪文」くらいに考えて構いません。

クラスの使い方について知りたい方はこちらの記事も参照してください。

 

オブジェクトの位置を変更するには、「transform.position = a;」のように記入してください。これで、a = (2, 2, 2)方向の成分を持ったベクトルを代入したことになります。

今回はaを位置として扱っていますが、aの方向に力を加えたりもできます。

ちなみに、丁寧に書く場合は「this.gameObject.transform.position = a;」となります。オブジェクトに直接アタッチする場合は自動的に「このオブジェクト」であるSphereが指定されるので、省略することができます。

 

Vector3 の足し算

Vector3の各成分に加算したいときは、「a.x += 1f;」「a.y += 1f;」「a.z += 1f;」のように記述します。

Vector3同士の足し算がしたいときは、以下のように記述してください。同様の結果が得られます。

上記のコードではVector3 のa と bを足し合わせることで座標を変更しました。これを図で表すとこのようになります。

 

 

Vector3 の引き算

 

 

ベクトル同士の引き算では、「Vector3 direction = b – a;」のように、「ターゲット — 自分の位置」です。これで、「自分の位置からターゲットへの方向と大きさ」を示します。

「b = a + direction」なので、現在地からターゲットへ移動したい場合は、「transform.position = a + direction;」のように使用します。

 

 

Vector3を使用した移動方法

・Transform.position += transform.Vector3 * Time.deltaTimeを利用した移動

 

Input.GetKey(“up”)で矢印キーの上を押したときに実行されます。

forwardはVector3 (0, 0, 1)と同じ意味です。なので、現在のSphereのpositionに、「transform.forward」でVector3 (0, 0, 1)を加算し続けることになります。

forward等の単位ベクトルを他にも知りたい場合は公式サイトでご確認下さい。

 

 

・Vector3.MoveTowards (Vector3 current, Vector3 target, float maxDistanceDelta)

 

 

指定した座標に向かって移動したいときに使います。

使い方は「Vector3.MoveTowards (基準となる開始座標, 到達したい座標, 移動距離)」です。

今回の場合、基準となる開始座標はSphereの現在の位置、到達点はCube、移動距離は speed * Time.deltaTime = 1 m/s です。

 

別の移動方法を知りたい場合はこちらもご覧ください

 

 

Vector3の長さを低負荷で取得「magnitude」「sqrMagnitude」

ベクトルの長さを取得するには「a.magnitude;」のように使用します。

長さの取得には三平方の定理を用いています(厳密には内積を使って「Mathf.Sqrt(Vector3.Dot(v, v))」で求めていますが、結果は同じで処理速度の問題です)。

これで、上記の例の場合、「magnitude = √(1^2 + 1^2) = √2 = 1.414…」となります。

しかしながら、ルートの計算は小数点以下が多く、計算に大きな負荷がかかります。そこで、Unity は「a.sqrMagnitude」の利用を推奨しています。

これは、magnitudeを2乗したもので、

となります。

これであれば、ルートよりも軽い負荷で計算が可能になります。

例えば、Cubeから常に2mだけ離れたい場合は以下のようなコードになります。

 

離れたい距離「distance = 2f」を定義して、その2乗「squareDistance = Mathf.Pow(2f, 2);」を取得。

「if(transform.position.sqrMagnitude > squareDistance)」で「長さの2乗 > 離れたい距離の2乗」のとき、MoveTowardsでCubeの方へ移動。

離れたい距離の2乗よりも短い距離になったら、(0, 0, 2)へ移動。

これで、常に2m以上離れているように見えます。円の式などを利用してdistanceを調整すれば全方位に対応できます。

 

 

Vector3 の長さを正規化して1にする「Normalize()」「Normalized」

正規化を行うと長さを1としたベクトルを作成できます。

使い方は、「a.normalized」「a.Normalize();」のように利用します。これらの違いは「読み取り専用」か「実際に代入するか」です。

「a.normalized」は読み取り専用で、「a.x」や「a.y」のように要素を参照しているだけです。

これに対して「a.Normalize();」はメソッドであり、実際にaの長さを1にします。なので、Normalizeしたaに対して「a *= 5f;」のようにすれば、長さが5のベクトルが得られます。

 

 

終わりに

フィア
やっぱりベクトル難しいよ…
カレン
Unityの場合は公式通り当てはめれば

なんとかなるとは思うんだけどね…

フィア
難しかった人は、一緒に数学から勉強しようね…

 

 

参考サイト

Unity DOCUMENTATION

 

げーむつくろ~

 

 

忙しい人のためのUnity入門講座へ戻る

 

すくまりゲームズの人気記事