公開日:2023/05/04  更新日:2023/05/04

UnityのVector3の構造体の使い方

 UnityのVector3とはX、Y、Zの値を持ち位置や方向を表せる構造体だ。
 この記事を読む前に、C#でのスクリプトの開き方、基本的な構文の作り方、変数、演算子がわからない場合は先に以下の記事で確認してほしい。
UnityのC#の書き方
UnityのC#の変数・演算子
if文の条件分岐

 Vector3は使用する機会が多いのでぜひマスターしておきたい。使い方を紹介していく。

Vector3の使い方目次

基本の使い方
作成方法色々
計算
ベクトルの大きさ
距離
距離の比較
正規化
目次にもどる

Vector3の基本の使い方

 以下のようにスクリプトのStartメソッドに記述し、ゲームオブジェクトのcube(何でも構わないが・・)にアタッチして再生してみよう。
 Vector3 a = new Vector3(3.0f,4.0f,5.0f);として、Vector3のxの値を3.0、yの値を4.0、zの値を5.0にしたVector3のaを作成している。
 数字の後ろにfをつけているのはVector3がfloat型(7桁までの浮動小数を持てる)の値を持つ構造体だからだ。
 a.y = 11f;としてyの値については11を代入しており、最初に入れた値を変更している。
 Debug.Log("x = " + a.x);として、 + a.xとすることでxの値を取り出し、ログに表示している。yやzも同様にログに出している。ログはx = 3、Y = 11、z = 5となる。
目次にもどる

Vector3の作成方法色々

 以下のようにVector3はnewを使わずとも作成可能である。
 特に使用頻度が高いのがVector3.zero;やVector3.up;だ。
 Vector3 h = Vector3.zero;とすることでhにはx、y、z全てに0と入る。0という値は初期値として適していることから使われることが多い。
 Vector3.upはワールドのY軸を示す時に使用することが多い(ワールドなので、ゲームオブジェクトの向きを変えても軸の方向が変化しない。ゲームオブジェクトの向きにより軸の方向も変えたい場合はtransformを使うこと)。
目次にもどる

Vector3での計算

 以下のようにスクリプトのStartメソッドに記述し、ゲームオブジェクトのcube(何でも構わないが・・)にアタッチして再生してみよう。
Vector3 のaとbを作った後にVector3 c = a + b;のように足し算を記述している。Vector3 cのログを出しており、(5.00, 7.00, 9.00)とコンソールビューに表示される。
その後はcとbが同じかどうかをif文で条件分岐しており、異なるのでelseの処理が行われ、「異なる」とログが出る。
Vector3は足し算などの計算や演算子による条件分岐などが可能となっていることがわかる。
目次にもどる

ベクトルの長さ

 ベクトルとは長さと向きを表す。
 Vector3.magnitudeでベクトルの長さを取得することができる。
 以下のようにスクリプトのStartメソッドに記述し、ゲームオブジェクトのSphereを作成してアタッチして再生してみよう。
Vector3 pos = transform.position;でゲームオブジェクトCubeの位置をx、y、zの値で取得している。
float length = pos.magnitude;でその位置のベクトルを出して、lengthに代入しログに出している。
Cubeを様々な位置に移動させた上で再生してみよう。原点(0, 0 ,0)から終点であるCubeの位置(x、y、z)までのベクトルの長さが表示される。


ゲームオブジェクト同士の距離を知りたい時にもベクトルの長さを求めればいい。例えばSphereとCubeを作成し適当に距離をはなして配置する。
その上でスクリプトを以下のように書き、Sphereにアタッチして再生してみよう。
[SerializeField] GameObject targetObject;と記述し、シリアル化(シリアライズ)している。インスペクター欄でtargetObjectはCubeを指定しよう。

続いてStartメソッドの中を見ていこう。
Vector3 pos1 = targetObject.transform.position;でCubeの位置をpos1に代入。
Vector3 pos2 = transform.position;でSphereの位置をpos2に代入。
float length = (pos1 - pos2).magnitude;でpos1とpos2の引き算をしてCubeとSphereの位置の差からベクトルを求めてlengthに代入し、それをログに出している。
これでCubeとSphereの間の距離を求めることができる。

例えば操作キャラと敵キャラとの距離を求めたい場合など、使える場面が多い。
目次にもどる

距離

 先ほど紹介した方法以外にも距離を計る手段はある。
 Vector3.Distanceを使えばいい。

 先ほどと同様にSphereとCubeを作成し適当に距離をはなして配置する。
 その上でスクリプトを以下のように書き、Sphereにアタッチして再生してみよう。
シリアル化してCubeを指定する点、SphereとCubeのtransform.positionを取得する点は同じ。
float kyori = Vector3.Distance(pos1, pos2);で2つのゲームオブジェクトの距離をkyoriに代入してログを出している。

目次にもどる

距離を比較する

 2つのゲームオブジェクト間の距離を出す方法としてVector3.magnitudeやVector3.Distanceを紹介したが、この2つは処理が重いという弱点を抱えている。

2点間の距離を比較したいだけであればVector3.sqrMagnitudeの関数を使おう。
この関数はベクトルの長さの2乗を求めることができる。
Cube、Sphere、Capsuleのゲームオブジェクトを作成し以下のように適当に距離を開ける。

 その状態でCubeに以下のスクリプトをアタッチして再生してみよう。

今までと同様にシリアル化を行っているので、インスペクター欄でtargetcubeにCube、targetcapsuleにCapsuleを指定しよう。
 Startメソッドではまず3つのゲームオブジェクトの位置を取得した。
 その後にfloat kyori1 = (pos1 - pos3).sqrMagnitude;としてCubeとSphereの位置の差をkyori1に代入。
 同様にfloat kyori2 = (pos2 - pos3).sqrMagnitude;としてCapsuleとSphereの位置の差をkyori2に代入。
 if文でkyori1 > kyori2で条件分岐し、それぞれでログが出るようにしてある。

 kyori1とkyori2のログで出てきているのはベクトルの長さが2乗された値だ。よってどちらが長いかの比較はできるが、実際の距離ではないので注意(この2乗を実際の距離にする計算をしていないためにVector3.magnitudeやVector3.Distanceと比較して処理が軽いのだ)。
目次にもどる

正規化

 Vector3.normalizedで正規化が可能である。
 正規化とはベクトルの長さを1とした単位ベクトルを取得することができる関数だ(ただし0や非常に小さい数値は0ベクトルとなる)。

例えば以下のようなスクリプトを作成しCube(何でも構わないが・・・)にアタッチして再生してみよう。

再生するとWSキーや↑↓キーで前後移動。ADキーや←→キー左右移動ができる。詳しくは以下の記事で紹介している。
Input.GetAxisについて
 例えば、WキーでZ座標方向に進み、DキーでX座標方向に進む。WDキーを同時に押して進んだ場合は斜めに進むことになる。その際の移動距離はWキーやDキーを単体で押した場合より長い。
 よって斜め移動した場合の移動速度が上がってしまい不自然なのが問題となる。
 前後左右に移動する場合と斜めに移動する場合で移動速度を同じにしたい。その場合にVector3.normalizedを使った正規化が役立つ。
 以下のようにスクリプトを書き換えてみよう。

 基本構造は先ほど紹介したスクリプトと同じ。
 Vector3のmukiを作成し、そこにVerticalとHorizontalの入力を代入している。
 続いてpos += (muki.normalized * speed);としている。muki.normalizedとすることで正規化されベクトルの長さが1の単位ベクトルとなる。斜め移動しようがベクトルの長さは変わらない。mukiはあくまで向きを示すだけのものになる。そこにspeedをかけて移動速度を操作している。
 再生すると前後左右の移動でも、斜め移動でも同じ移動速度となる。
UnityのC#の基礎まとめへ戻る

page top