Unity>物理シミュレーション
Unity内における船と錨の相互作用の実装
海戦アクション作るにあたって、クラブホーリング(clubhauling)のアクションを実装してみたくなりました。 クラブホーリングとは大航海時代から存在する船舶の緊急旋回(回避)技術で、船首の錨を投錨しながら旋回、錨の着底時にはたらく錨からの張力をトルクとして急旋回(ないし急停止を目的とする場合もある)を試みる技術。言葉にするよりも以下のパイレーツオブカリビアンの描写が一目瞭然
このアクションをUnityのゲーム内で実装していく
錨の状態遷移
ゲームの中で船と錨との相互作用をシミュレーションするにあたっては、以下の4つの状態があればよさそう
- OnShip: 錨は船上
- LetGo: 錨を海中に投げ入れ、惰性的に落下させている状態
- Anchoring: 海中の錨を船上に向かって巻き上げている状態
- WeighUp: 錨が着底し、ロープを通した張力が最大限有効な状態
ちなみに現代の船では我々が錨と聞いてイメージする錘と爪の抵抗だけでは船の係留力としては不十分で、それをつなぐ金属製の鎖を通して生じる抵抗力こそ極めて重要で、場合によってはそちらの方が抵抗力全体としては大勢を占めるらしい(ゲーム内では鎖ではなくロープという設定で、その点はモデリング対象外としよう)
悩んだ末に走錨状態(錨が静止摩擦力を越えて動摩擦状態に移行した状態)の実装は見送ることに
状態遷移図
これらの状態の可能な遷移関係は以下の通り
各状態でのダイナミクスの使用は以下の通りの仕様とする
- OnShip: 自船とともに移動
- LetGo: 自由落下。ただし一律に4.0sで海底に到達するものとする
- Anchoring: 位置は固定
- WeighUp: 錨から船首への相対ベクトル方向に、常に3.0m/sの程度の相対速度で巻き上げる
相互作用
基本的に物理シミュレーションはスクラッチで実装していく方針だが、数値計算の際に撃力の扱いが難しいなと感じていたところ、 以下の記事に出会った
- 0から始めるUnity物理演算⑤衝突と力積 - Nexus Milo Lab. Blog
- 撃力のような瞬時の力をモデル化しようとすると、unityのように1/30[sec]ぐらいのdeltaだと近似が甘く、不安定な挙動になりやすい
- そこで撃力の厳密なモデル化は諦め、むしろあるべきdv、ないしモーメンタムの差分を先にモデル化する
- そこから逆に運動方程式: から平均的な力を求め、トルク計算にはこのを用いることで結果がだいぶまともに見えるようになった
TBC
参考資料
- Age of Sail | Historic Naval Ships Association
- 大航海時代の航海術についてかなり詳細に解説されている
- 情報メディア実験
- 物理シミュレーション上はこの記事が勉強になりそうなのでアップデート時にトライしてみようかな。