Unity Vector3 三平方の定理とベクトル

Unity

ベクトル

Vector3

ベクトルの (x *x+y* y+z* z) の平方根の長さを返します
magnitudeはベクトルの長さを返す。

Unity リファレンス

こう書いてあります。
なんのこっちゃってことですよね。
一言でいうと、ベクトルを返しています。

Unityでもよく出てくるベクトル。
定義するなら大きさと方向を持った量
方向はxyzの3次元の集合で表せられます。
大きさは始点から終点への長さ、距離です。
なぜx,y,zの座標の二乗の和の平方根がベクトルになるのか。
それは三平方の定理が関係しています。

おまじないを書いて普通に使えればいいやって方もいると思いますが、何がどうなっているのか、義務教育で習った範囲でベクトルについて復習します。

三平方の定理(ピタゴラスの定理)


黒くて大きい四角形も赤くて小さい四角形も正方形であると仮定します。
急いでいい加減に作りました。とにかく正方形です。

正方形であるということは角は全て直角です。
正方形なので辺cの大きさも全て同じ。

そうなると直感的に辺の長さが全て同じである直角三角形が4つあることが分かると思います。
(辺cの長さとその反対側にある直角の大きさはどの三角形も変わりません。
ということはそれぞれの三角形の辺aとbは同じ長さでないと三角形が成り立たないはずです。)

黒い四角形の面積は

S = (a + b)^2(2乗)

辺の長さの2乗(縦×横)になります。
そしてもう一つ黒い四角形を求める方法があります。
それは赤い四角形と直角三角形4つの面積を足すことです。

S = c^2 + 4(1/2ab)

赤い四角形の辺cの2乗と三角形の底辺と高か三角形×2が4つ分ですね。
先に作った式とこの式は等式になります。

(a + b)^2 = c^2 + 4(1/2ab)

これを計算すると

c^2 = a^2 b^2

短い二つの辺の和の2乗が長い斜辺の2乗になります。
三平方の定理の証明です。

先ほどの

ベクトルの (x *x+y* y+z* z) の平方根の長さを返します
magnitudeはベクトルの長さを返す。

(a + b)^2 = c^2 + 4(1/2ab)

これを書き方だけ直すと

c*c = a*a + b*b

なので雰囲気は似てきました。

ベクトル

辺cがベクトルです。
三平方の定理にしたがってやってみます。
x軸方向の長さの2乗とy軸方向の長さの2乗の和です。
点Pの座標はx=3,y=4です。

c^2 = 3^2 + 4^2
c^2 = 9 + 16
c^2 = 25

5*5は25なので25の平方根は5ですね。
一緒にcの二乗もはずしてしまえば

c = 5

となります。
つまり、2次元の座標の2乗の和の平方根がベクトルということになります。
3次元でも同じ、座標x,y,zの座標を2乗し足し合わせて、平方根をとれば3次元のベクトルを表現することが出来るのです。

Unityのリファレンスにあったこれ。

ベクトルの (x *x+y* y+z* z) の平方根の長さを返します
magnitudeはベクトルの長さを返す。

Vector3は文字通りベクトルを扱うクラスで、magnitudeは3次元の座標を取得し2乗してその平方根、つまりベクトルを返しているのです。
インスタンスを生成するときに渡す3つの座標はベクトルを計算するのに必要なものなんですね。

Vector3

話をUnityに戻します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

Rigidbody rb;
private float Speed;
public class MyObject : MonoBehaviour {
  void Start()
    {
	rb = GetComponent();
		
    }
    void Update () {
        float x = Input.GetAxis("Horizontal") * Speed;
        float z = Input.GetAxis("Vertical") * Speed;
        vec = new Vector3(x,0,z);
        rb.AddForce(vec);
    }
}

まずStart()でRigidbodyのコンポーネントを取得。
もう一度言いますが、ベクトルは「大きさ」と「方向」を持った量です。
Update()でfloat型の変数にx(横の方向)座標とy(この場合は座標0)z(前後の方向)座標、それにSpeed(大きさ)の値を乗じて代入します。

Vector3に作っておいた二つの値xとzの座標、それにy(上下)だけ0にしてに渡してベクトルのインスタンスを生成します。
このベクトルは当然方向と大きさを持っています。次に描画されるフレームにおける座標ですかね。

これをRigidbody.AddFroe()に引数として渡してAddForce内部で重力による影響の挙動を計算してもらいます。

この辺は推測でもっと調べないといけませんが、AddForce()はRigidbodyに設定されている加速度や質量や摩擦係数、空気抵抗の値に応じてTransform.positionに変更を加えているのだと思います。
質量や加速度や摩擦、空気抵抗

力=質量₊加速度

です。加速度はSpeedで質量はInspectorに表示されるMassです。
物理的には力を加えると少しづつ速くなりますよね。
ゲーム内だと少しづつ移動量が大きくなる感じです。
なのでRigidbody.AddForce()はこのゲーム内での移動量を計算してRigidbody.positionを変更します。
見かけ上は物理的な影響を受けているように見えます。

空気抵抗や摩擦力は割愛します。

Transform
オブジェクトの位置、回転、スケールを扱うクラス
シーン内のすべてのオブジェクトは Transform を持ちます。

Transformリファレンス

Rigidbody.position allows you to get and set the position of a Rigidbody using the physics engine. If you change the position of a Rigibody using Rigidbody.position, the transform will be updated after the next physics simulation step. This is faster than updating the position using Transform.position, as the latter will cause all attached Colliders to recalculate their positions relative to the Rigidbody.

Rigidbody.positionはRigidbodyのpositionのセットとゲットを行います。
Rigidbody.positionによりRigidbodyの位置を変えた場合、transformは次の物理シミュレーションステップで更新されます。
Rigidbody.positionはTransform.positionを使用するより早く更新されます。
その後アタッチされたコライダーはそれぞれの相対位置をRigidbodyの位置を元に計算しなおします。

Rigidbody.positionリファレンス

Transformは衝突や摩擦、抵抗を考慮しないので他のオブジェクトの位置や重さは無視できます。
仮に移動の軌道上にあっても関係ありません。
そのオブジェクトだけを更新すればいいのです。
しかしRigidbodyがアタッチされたオブジェクトは常に他のオブジェクトからの影響を考慮しないといけません。
全く関係なさそうなオブジェクトが動いたとしてももしかすると衝突するかもしれません。
なのでRigidbodyは先に物理シミュレーションを行い、その計算結果をもとにゲームオブジェクトの位置情報を変更します。
そのためRigidbodyがアタッチされたオブジェクトは他のオブジェクトが動くとその都度その位置や回転を再計算しなければならないため計算量が増大し処理が重くなるのでしょう。

Input.GetAxis()は移動した方向が右なら1左なら-1、動いていなければ0。
スティックとかだと倒した軸の角度を乗じて移動量を決定しています。
プログラミングおすすめ書籍

おすすめ書籍

なぜプログラムが動くのか。
平易な言葉で学べますが、初心者には難しいかもしれません。
でも読み終わった頃にはなんとなく理解しているでしょう。
初心者には家にあって損はありません。

UNIXの思想を学べます。
高尚なタイトルですが、コードはおろか難しい言葉も殆どありません。取っ掛かりに最適でその後のプログラミングに対する理解を一変させます。
なぜならこの思想はプログラミングそのものだからです。
一読の価値ありで、これは良書なので今後紹介したいと思っています。

まだまだありますがまたの機会に紹介したいと思います。

Unity コンピューター プログラミング 勉強
スポンサーリンク
himazinをフォローする
私の頭の上の消しゴム

コメント

タイトルとURLをコピーしました