Unityで振り子をシミュレーションしたい!
こんにちは、カキレモンです。
表題のとおりです。Unityで振り子を作るならRigidBodyとHingeJointなどを組み合わせて使うのが定石だと思いますが、今回はRigidBodyの代わりに運動方程式を使って振り子の動きをシミュレーションしてみます。
ちなみに角速度の計算を使った方法がすでに書かれています。今回はこれとは違う方法でやってみることにしましょう。
振り子の運動方程式の導出は、このサイトを参考にしました。
運動方程式
運動方程式は、物体に働く力と加速度の関係を表しています。要するに、ある瞬間に物体が受ける力が分かれば加速度を計算できるので、それをもとに物体の速度や位置を更新する、という計画でやってみましょう。
さて、振り子の運動方程式は次の式で表されます。
(『物理の見つけ方』より引用)
ここで、太字のアルファベット(xとg)はベクトルを表しています。またxの上の点は「微分」を表すサインで、点が2つのものは二階微分すなわち加速度、1つのものはもちろん速度に対応します。右辺にあるxTgというのはベクトルの内積として計算することにします。また、最後のxにかぶっている笠のような記号は、ベクトルを正規化していることを表しています。
というわけで式も分かったので、さっそくやっていきましょう。
いざUnityへ
なにはともあれ、とりあえずそれっぽいスクリプトを書きました。
上記の運動方程式の両辺を質量で割ったものをつかって計算しています。また、Gizmoを使って重力や拘束力の大きさを線で表示するようにしてみました。
では、実際に動かしてみましょう。
おっ、これは楽しそうですね!
なんていうか、とても活力に溢れていて感情豊かです。
ここでnoteを書き終えるわけにはいかないので、なんとかしましょう。
もしかして:タイムステップが大きすぎる
環境にもよりますが、UnityでUpdateは1秒間に大体60回くらい呼ばれています。つまり、位置や速度の更新はその頻度で行われるということです。
計算自体は変えずに、この更新頻度を雑に上げてみました。
stepNを変えることで1フレームに複数回のステップを回すことができます。果たしてこれで精度が上がるのでしょうか?
実際にやってみましょう。
stepN=10です。ぱっと見よさそうですが、だんだん振れが偏ってきている気がしますね。
stepN=1000です。これは安心して見ていられますね。
今回はこれでいいことにしましょう。ちなみに動画は省略しますが、stepN=1000000とかにするとバグります。ちょっと面白いので手元でやってみてください。
おわりに
かなり雑な方法で物理シミュレーションをしました。うっかりその道の人に見つかったらグーでひっぱたかれそうで怖いです。ゆるして……
ところで今回はUnityのバージョンを2020にしてやってみたところ、Spriteの画像がいっぱい増えていて感動しました。かねてより"knob"の粗さには辟易したところです。拡大してもザラつかないって素敵。
そういうことで本日はここで〆です。
それでは、(願わくば、)また。
この記事が気に入ったらサポートをしてみませんか?