スクリプトによるRigidbodyに頼らない放物移動【Unity】

終点への放物移動

Unityでの放物移動の記事はRigidbodyを用いたものがほとんどだったので、高校物理の方程式を使ったスクリプトベースの放物移動を紹介します。

始点と終点のy座標のズレにも対応できる放物移動になっています。

動きのベースとなる値は、終点座標と終点座標につくまでの滞空時間です。

高校物理 ~斜方投射~ 

斜めに投げる斜方投射は、

①水平方向(横)= x,z成分

②鉛直方向(縦)= y成分

2種類に分けて考えるのでした。

 

Point
①水平方向は一定の速度
②鉛直方向には重力加速度で速度が変化

水平方向 x,z成分

指定した滞空時間が経ったらちょうど終点につくように、xとz成分を時間に比例して変化させるだけです。Unityを使っているので、Lerp関数で対処できます。

Lerp関数 リファレンス

https://docs.unity3d.com/ja/2017.4/ScriptReference/Vector3.Lerp.html

鉛直方向 y成分

鉛直方向である、鉛直投げ上げの公式は3つありましたが、ここでは、始点と終点のy成分の差分(変位)を代入できるy滞空時間を代入できるt が用いられている変位の式を使います。

$$変位\quad\color{blue}{y}=v_0\color{green}{t}+\frac{1}{2}g\color{green}{t^2}\quad ・・・①$$

ここで、 y と t は私たちが決めるものなので、分かっている数値です。残りのy方向の初速度voが分からないので左辺に置くよう変形します。

$$v_0=\frac{\color{blue}{y}-\frac{1}{2}g\color{green}{t^2}}{\color{green}{t}}=\quad ・・・②$$

上の式に、以下のように私たちが指定する要素を代入した初速度をvnとします。

$$v_n=\frac{\color{blue}{始点と終点のy成分の差分}-\frac{1}{2}g\color{green}{滞空時間^2}}{\color{green}{滞空時間}}\quad ・・・③$$

最終的に鉛直方向の初速度vnを初出の①式に代入した④式基づいて、変化する時間tを代入してスクリプトで動かしていきます。

$$変位\quad\color{blue}{y}=\bf{\color{orange}{v_n}}\color{green}{t}+\frac{1}{2}g\color{green}{t^2}\quad ・・・④$$

 

スクリプト

コールチンを用いて実装しています。

Jump関数

初期値 21~23行目

初期位置、始点と終点のy成分の差分、前項③式を用いて鉛直方向の初速度vnを求めています。

放物運動による座標更新 26~32行目
時間tの更新 26行目

for文で滞空時間を満たすまで変数tにTime.deltaTimeを足して繰り返していきます。speedRateはオプションで滞空時間を基軸とした動きにおける再生速度です。ここは仮で1倍速にしてます。

水平方向の座標 28行目

Lerp関数の第3引数は0~1に収めないといけないため、flightTimeで割っています。

鉛直方向の座標 29行目

前項④式に基づいています。

1フレーム経過 31行目

コールチンのfor文内で使われた

yield return null;

は 中断するという意味で1フレーム経過したのち、再びfor文内の28行目からスタートします。そのため、for文で一気に計算するのではなく、フレームごとに座標結果を更新していくことができます。

まとめ

コールチンを組み合わせることで、毎フレームごとの座標更新ができるというのが私的に目新しいところだと思いました。

本記事は、今読んでる上の「Unityゲーム プログラミング・バイブル」に掲載されていたものを元に私なりに解説してみたものになります。

細かいセクションで内容が分かれていたので、濃い内容かどうか不安でしたが、空き時間に2年ほど触ってきた私ですが、知らない内容やソースコードのノウハウがあったので読んでみる価値はあると思います。