【Unity】RigidbodyのCollision Detection(衝突の検知)を変えて実験

【Unity】RigidbodyのCollision Detection(衝突の検知)を変えて実験

物理的な運動をさせるRigidbodyにおいて、衝突の検知はかなり重要です。

衝突を検知できなければ、物体を透過してしまいますからね。

……と言っておきながら、高速で移動するRigidbodyは結構物体を透過することがあるんです。

そんなときはRigidbodyコンポーネントのCollisionDetection(衝突の検知)の設定を変えて、ちゃんと検知してもらいましょ。

 

環境

macOS 10.13 High Sierra

Unity2018.1.0f2

4月末にUnity2018が出てたので早速使ってみました。

Rigidbodyについて

Rigidbodyのアタッチ方法や各設定項目の説明は、以下の記事で解説しています。

ざっくり言うと、Unityで物理演算を使うために必要なコンポーネントです。

今回はその中でもCollision Detection(衝突の検知)がテーマ。

Rigidbodyのパラメータ
Rigidbodyのパラメータ

 

Collision Detection(衝突の検知)について

Collision Detectionは日本語訳すると「衝突の検知」。分かりやすくて素敵。

検知方法は『Discrete』、『Continuous』、『ContinuousDynamic』の3通り。

Discrete』は離散的に衝突を検知します。FixedUpdateが呼ばれたタイミングで衝突を確認するため、そのときにColliderが重なっていないのであれば衝突したと見なされません。

この設定だと高速で移動しているときはオブジェクトを通り抜けることがあります。パフォーマンス的には一番いいのですが、肝心の衝突を検知できないのは困りもの。そんなときは次の設定値を使います。

Continuous』は、このRigidbodyを持ったオブジェクトの進路上に、Rigidbodyを持っておらず、かつColliderを持つオブジェクトがあれば、FixedUpdateの間であっても連続的に衝突を検知するモード。Continuousはそのまま「連続的に」といった意味。

衝突の対象は壁などのRigidbodyを持たないオブジェクトです。壁にRigidbodyを持たせると吹き飛んだりするので、衝突をさせるためにColliderだけ持たせることが多いです。

進路上に対象のオブジェクトが存在することを確認するため、『Discrete』に比べると重い処理になります。

ContinuousDynamic』は『Continuous』のケースに加えて、相手がRigidbodyを持っていても、相手のCollision Detectionが『Continuous』または『ContinuousDynamic』であれば連続的に衝突を検知してくれるモード。衝突検知の精度ではこれが一番です。

動いているRigidbodyの軌道まで計算するので、パフォーマンス的には激重さんです。なので高速で動くオブジェクトだけに絞った方がいい感じ。

 

使用の条件

『Continuous』と『ContinuousDynamic』には条件があって、連続検知してくれるコライダーが決まっています。

スクリプトリファレンスを見ると、Sphere Collider、Capsule Collider、Box Colliderを使っているときに連続検知をしてくれます。Unityが事前に形を知っているコライダーで計算してくれるみたい。

ユーザー側で形を決められるMesh ColliderやTerrain Colliderでは連続検知をしてくれないので注意。

3Dモデルが複雑な形をしているのであれば、複合コライダーとしてSphere Collider、Capsule Collider、Box Colliderを組み合わせて使ってみるのも一つの手だと思います。

複合コライダーについては、マニュアルのRigidbodyの項目をご覧あれ。

オブジェクトのすり抜け

オブジェクトのすり抜けについては、テラシュールブログさんの以下の記事がとても参考になります。

ここでは、衝突する側とされる側でそれぞれのCollision Detectionを変え、衝突がどうなるか見てみましょ。

衝突する側として、以下の3つのボールを用意します。

  • Collision Detection : Discrete
  • Collision Detection : Continuous
  • Collision Detection : ContinuousDynamic

Collision Detectionの設定のみ変え、他の値はRigidbodyのデフォルトのままとします。

これらのボールに、同時に力を与えた時の運動を観察。ForceModeはImpulseとし、加えた力の大きさは画面左上に表示しています。FixedUpdate()のスキをついて欲しいので、強めの力で飛び出してもらいましょ。

まずは加える力を小さめにして、ゆっくりと衝突させてみます。衝突相手のピンクのオブジェクトはRigidbodyを持っておらず、Box Colliderのみを持った壁です。

まずはゆっくり衝突させる
まずはゆっくり衝突させる

 

この壁を衝突相手として、加える力を大きくしてみます。『Discrete』に設定したボールはすり抜けてしまいました。一方で、『Continuous』と『ContinuousDynamic』は、飛び出す速度は同じにも関わらず、ちゃんと衝突できていますね。

勢いよく飛び出してみる
勢いよく飛び出してみる

 

続いて、衝突相手がRigidbodyを持っている場合。緑色のオブジェクトはRigidbodyを持っており、動かないようにmassとdragを300にしています。このオブジェクトでは、Collision Detectionの値を『Discrete』にしています。

『Discrete』と『Continuous』はすり抜け、『ContinuousDynamic』だけきちんと衝突しています。

立ちはだかる壁型モンスター(仮)
立ちはだかる壁型モンスター(仮)

 

マニュアルにある通り、相手がRigidbodyを持っているかどうかで選択すべき設定が異なるのがわかります。

 

動く物体とぶつけてみる

上では壁相手の衝突だったので、今度は動いていて、かつ衝突相手もCollision Detectionの値を変えてみましょうか。

画面左のオブジェクトと画面右のオブジェクトに、同じ大きさで向きが逆の力を加えます。相対速度が倍なので超高速で駆け抜けます。

まずは衝突相手(ピンクのボール)が『Discrete』の場合です。一瞬のことで見分けにくいですが、ピンクのボールが画面左まで突き抜けているので、衝突が起こらなかったようです。

画面左にいる『ContinuousDynamic』のボールもすり抜けていますね。壁のように動かないオブジェクトとの衝突は検知してくれましたが、高速で動くオブジェクトだと無理なようです。

そして誰もいなくなった
そして誰もいなくなった

 

続いてピンクのボールが『Continuous』になっている場合です。一方が『ContinuousDynamic』であれば、『Continuous』相手の衝突を検知してくれました。

ごっつんこ
ごっつんこ

 

両方のオブジェクトで衝突を検知できているみたい。

OnCollisionEnterで確認
OnCollisionEnterで確認

 

最後にピンクのボールが『ContinuousDynamic』になっている場合です。『ContinuousDynamic』同士はもちろんのこと、上のケースと同じように『Continuous』とも衝突。

ごっつんこx2
ごっつんこx2

 

4つ分のデバッグ文が出力されているので、バッチリ検知されています。

OnCollisionEnterで再度確認
OnCollisionEnterで再度確認

 

実験結果のマトリクス

実験した結果を表にすると以下のようになります。

Collision Detection Rigidbodyなし Rigidbodyあり
Discrete Continuous ContinuousDynamic
Discrete × × ×
Continuous × ×
ContinuousDynamic

○が連続的な衝突の検知が可能、×は連続的な検知ができない組み合わせです。

△にしているところは、Discrete側が止まっている場合に検知できることがあります。

……場合によっては検知してくれる、なんてのを過信するのは禁物なので、高速で動くオブジェクトにはちゃんと『ContinuousDynamic』を設定しておいた方がいいですね。

まとめ

Rigidbodyをアタッチしたオブジェクトがすり抜けるのを防ぐCollisionDetection。

連続的に衝突を検知してくれる優れものなので、条件に気を付けつつ、高速に移動する物体の衝突をガンガン検知しましょ。

アセット作ってます!

CTA-IMAGE

Unityでの開発に役立つアセットを作っています。

3DダンジョンRPGを開発するスピードを200%加速するAssetや、ファンタジーRPGのダンジョンを彩るパーツを取り揃えています。

特に3DダンジョンRPGのゲームを1から作るのは結構時間がかかります。ダンジョン部分の作成はこうしたアセットを使って、開発をブーストさせてみませんか?