どうもなおゆです。
今作っているゲームで、床の上に食べ物オブジェクトがポトポト落下するようにしました。
しかし、どうやら何回かに一回の確率でバナナが床をすり抜けてしまうようです。床をすり抜けたバナナはそのまま奈落にGO!しますが、それだと困るので修正していきます。
オブジェクトのすり抜け(コライダーの衝突判定漏れ)を防止する
衝突判定を「連続的かつ動的」にする
結論から言うと、Rigidbodyがついているオブジェクトの衝突判定(collision Detection)を「連続的かつ動的」 (ContinuousDynamic)に修正してください。
それですり抜けを防止できます、はい。(笑)
なぜすり抜けが発生するのか
一応、今後の備忘のために原因をまとめます。
現在の状態は上の画像のとおり、それぞれにコンポーネントをアタッチしています。
- 落下してくるバナナにはRigidbodyとMeshColliderのコンポーネント
- 受け止める床にはBoxColliderコンポーネント
オブジェクト同士の衝突はRigidbodyを持ったオブジェクトがCollider系に接触した際に検知されますが、その精度を調整する項目がRigidbodyの衝突判定( collision Detection )です。
検知頻度のイメージが下の図です。
バナナと床が接触したタイミングでちょうど検知されれば、すり抜けは発生しません。
検知をしていないタイミングで床に接触した場合すり抜けが発生します。特に高速で移動するオブジェクトなど、オブジェクト同士の接触が一瞬で終わる場合などにすり抜けがよく発生します。
それでは、それぞれの衝突判定についてUnityのスクリプトリファレンスを見てみましょう。
非連続的( Discrete )
高速で動くオブジェクトの衝突に関して何の問題もないのであれば、 これは物理演算のパフォーマンスに多大な影響を与えますのでデフォルトの CollisionDetectionMode.Discrete 設定のままにしておいてください。
これが初期設定ですね。検知頻度は「低」といった感じです。書いてあるとおり、高速で動くオブジェクトなどが存在しない場合は初期設定で十分です。
連続的( Continuous )
その他の衝突が必要なオブジェクトには CollisionDetectionMode.Continuous を設定
検知頻度は「中」といった感じです。
連続的かつ動的( ContinuousDynamic )
最高の結果のために、高速で移動するオブジェクトはこの値を CollisionDetectionMode.ContinuousDynamic に設定
これが最も検知頻度が「高い」モードです。
じゃあ、とりあえず全てのオブジェクトを「連続的かつ動的」にしたら良いじゃん!と思うかもしれませんが、デメリットもあるのです。
衝突検知の回数を上げると検知漏れは減りますが、もちろんそれだけ頑張っているという事ですので負荷がかかります。イメージはこんな感じです。
結論
作成するゲームの種類によって使い分けてください。処理速度と判定のバランスが大事です。検知頻度の低いモードから初めて様子を見ていくのがベターでしょうか。Let’s デバッグ!
コメント
[…] 【Unity】オブジェクトのすり抜けを防止する方法 […]