sharijyuのログ置場

最近はUnityで海戦アクションゲームを作っています。開発に限定されない随想ログ置場

Unity>物理シミュレーション

Unity内における船と錨の相互作用の実装

海戦アクション作るにあたって、クラブホーリング(clubhauling)のアクションを実装してみたくなりました。 クラブホーリングとは大航海時代から存在する船舶の緊急旋回(回避)技術で、船首の錨を投錨しながら旋回、錨の着底時にはたらく錨からの張力をトルクとして急旋回(ないし急停止を目的とする場合もある)を試みる技術。言葉にするよりも以下のパイレーツオブカリビアンの描写が一目瞭然

www.youtube.com

このアクションをUnityのゲーム内で実装していく

錨の状態遷移

ゲームの中で船と錨との相互作用をシミュレーションするにあたっては、以下の4つの状態があればよさそう

  • OnShip: 錨は船上
  • LetGo: 錨を海中に投げ入れ、惰性的に落下させている状態
  • Anchoring: 海中の錨を船上に向かって巻き上げている状態
  • WeighUp: 錨が着底し、ロープを通した張力が最大限有効な状態

ちなみに現代の船では我々が錨と聞いてイメージする錘と爪の抵抗だけでは船の係留力としては不十分で、それをつなぐ金属製の鎖を通して生じる抵抗力こそ極めて重要で、場合によってはそちらの方が抵抗力全体としては大勢を占めるらしい(ゲーム内では鎖ではなくロープという設定で、その点はモデリング対象外としよう)

悩んだ末に走錨状態(錨が静止摩擦力を越えて動摩擦状態に移行した状態)の実装は見送ることに

状態遷移図

これらの状態の可能な遷移関係は以下の通り

anchor state

各状態でのダイナミクスの使用は以下の通りの仕様とする

  • OnShip: 自船とともに移動
  • LetGo: 自由落下。ただし一律に4.0sで海底に到達するものとする
  • Anchoring: 位置は固定
  • WeighUp: 錨から船首への相対ベクトル方向に、常に3.0m/sの程度の相対速度で巻き上げる

相互作用

基本的に物理シミュレーションはスクラッチで実装していく方針だが、数値計算の際に撃力の扱いが難しいなと感じていたところ、 以下の記事に出会った

  • 0から始めるUnity物理演算⑤衝突と力積 - Nexus Milo Lab. Blog
    • 撃力のような瞬時の力をモデル化しようとすると、unityのように1/30[sec]ぐらいのdeltaだと近似が甘く、不安定な挙動になりやすい
    • そこで撃力の厳密なモデル化は諦め、むしろあるべきdv、ないしモーメンタムの差分を先にモデル化する
    • そこから逆に運動方程式:  \tilde{F} = m\frac{dv}{dt}から平均的な力を求め、トルク計算にはこの \tilde{F}を用いることで結果がだいぶまともに見えるようになった

TBC

参考資料