Skip to main content

線型代数学

ベクトル

 ベクトルとは、一般的には「大きさと向きをもつ量」であり「矢印で表すことのできる量」である。

image.png

 2次元のベクトルは2つの成分(x, y)があり、3次元の場合は3の成分(x, y, z)がある。Unityでは Vector2Vector3 の構造体があり、それぞれのベクトルを作成ができる。

Vector2 vec2D = new Vector2(vx, vy);     // vxとvyはfloatである
Vector3 vec3D = new Vector3(vx, vy, vz); // vzもfloatである

 ゲームの中で、ベクトルをよく使うものである。例えば、3D空間で、キャラクターの速度が「左向き:秒速2メートル、前方:秒速10メートル」であるとしたら…

// 3D空間だと、x:左右、y:上下、z:前後
Vector3 velocity = new Vector3(-2, 0, 10);

 また、ゲームの場合は、向きと量はもちろんそうであるが、その他に「位置」もベクトルで表現する。

// プレーヤーはシーンの中心点から前方100メートルにいる
Vector3 playerPosition = new Vector3(0, 0, 100);

演算

 やはり、ベクトルは重要なので、ベクトルの演算を学ばないといけない。

加算

 2つのベクトルを足すことができる。その結果は各成分の足し算である:

2次元の場合

image.png

3次元の場合

image.png

Unityでは「+」の演算子で2つのベクトルを足すことができる

Vector3 v = new Vector3(vx, vy, vz); // vx, vyとvzは何かのfloat型の数値
Vector3 w = new Vector3(wx, wy, wz); // wx, wyとwzは何かのfloat型の数値
Vector3 vw = v + w;

 幾何学的に、足し算は2つの矢印を連続し、1つ目のベクトルの始点から2つ目のベクトルの終点までに新しいベクトルを作成するイメージ:

image.png

減算

 引き算は同じ形で行う:

image.png

Vector3 v = new Vector3(vx, vy, vz); // vx, vyとvzは何かのfloat型の数値
Vector3 w = new Vector3(wx, wy, wz); // wx, wyとwzは何かのfloat型の数値
Vector3 vw = v - w;

 幾何学的には、引くベクトルの向きを反転してから連続に繋がる

image.png

練習

加算と減算を使い、2つのオブジェクトを相対的に移動

  • シーンに2つの3Dゲームオブジェクトを追加し、距離的に放してください。
    • 1つ目の名前は「Control」
    • 2つ目の名前は「Follower」
  • スクリプト「VectorTest」を作成し…
    • Follower の初期位置を取得
    • Control の初期位置を取得
    • Control をシーン内で動かしたら、Follower が移動を真似する。
スクリプト:VectorTest
// ベクトル演算の練習」
public class VectorTest : MonoBehaviour
{
    // 移動すべきのオブジェクト
    [SerializeField] private GameObject control;

    // controlを追跡するオブジェクト
    [SerializeField] private GameObject follower;

    // controlの初期位置
    private Vector3 controlStart;

    // followerの初期位置
    private Vector3 followerStart;
    
    private void Start()
    {
        // 初期位置を取得
        followerStart = follower.transform.position;
        controlStart = control.transform.position;
    }

    private void Update()
    {
        // 移動量を計算(初期位置からどれぐらい移動したのか?)
        Vector3 move = control.transform.position - controlStart;
        
        // followerを更新
        follower.transform.position = followerStart + move;
    }
}