【Unity】Box Colliderの重複は何フレームで解消されるのか実験する

【Unity】Box Colliderの重複は何フレームで解消されるのか実験する

Unityで衝突と言えばColliderですが、Colliderコンポーネントをアタッチされたオブジェクトは、お互いが重ならないように処理されます。

『Scene』ビューで重ねて配置しても、ゲーム実行時にColliderが重ならない位置まで移動させられます。

この時、重複って何フレームで解消されるんでしょうかね。

重箱の隅をレーザーで突くような細かい話ですが、気になったものは調べるスタイルでいきましょ。

 

環境

macOS 10.13 High Sierra

Unity2018.1.0f2

Colliderについて

Colliderの種類については以下の記事で紹介しています。

今回は主にBoxColliderを使って実験してみます。

コマ送りで確認

知っている人も多いと思いますが、Unityのゲーム実行はコマ送りで進めることができます。ゲーム実行ボタンの右が一時停止ボタン、その右がStep(コマ送り)ボタンです。

コマ送りできるのだポッター
コマ送りできるのだポッター

 

フレーム毎に描画できるので、今回注目しているような細かい話で威力を発揮します。

一時停止ボタンを押した状態でゲームを開始すると1フレーム目で停止した状態になるので、そこからコマ送りしていきます。

観察の対象

実験で使うオブジェクトは以下の通り。

  • Colliderをアタッチしたオブジェクトを2種類用意
  • オブジェクトの占有領域が重複するようにシーンに配置
  • ゲーム開始時はRigidbodyなし、10フレーム経過後にRigidbodyをアタッチ
  • Cubeの大きさは4とする
  • PositionのXは黄色が0, ピンクが2とし、Y, Zは同じ値にする
  • Time.frameCountを使ってゲーム開始からのフレームカウントを表示
  • 接触が終わったことはOnCollisionExit()で確認
オブジェクトを重ねる
オブジェクトを重ねる

 

Colliderの重複が解消された後は斥力が働いたかのように反対方向に飛び出します。この飛び出す様子は以下の記事で観察したのですが、今回の実験はその延長線上にあります。

Rigidbodyがない状態ではColliderが重なっていてもオブジェクトは動きませんが、Rigidbodyをアタッチした場合は重ならない位置まで動きます。

10フレーム経過後にRigidbodyをアタッチするようにしているのは、ゲーム開始時は処理が立て込んでいるためです。この実験用のシーンではStart()にいっぱい処理が入ってるんです……。

 

実際にやってみよう

frameCountが10になるまでコマ送りで飛ばして、11フレーム目でRigidbodyがアタッチされてから何フレームでOnCollisionExit()が呼ばれるかを確認します。

5フレーム待ちで良かったかなーと思いつつ、11フレーム目になりました。このフレームで黄色のオブジェクト、ピンクのオブジェクトの双方にRigidbodyがアタッチされました。この段階ではまだ動きません。

11フレーム目でRigidbodyがアタッチ
11フレーム目でRigidbodyがアタッチ

 

続いて12フレーム目。黄色いオブジェクトは左へ、ピンクのオブジェクトは右へ移動を開始しました。

それぞれの移動距離は0.8です。

黄色オブジェクトの移動距離 + ピンク色オブジェクトの移動距離 + 最初の中心の距離(2m)がCubeのサイズである4を超えていれば、距離の上ではColliderの重複が解消されたことになります。

12フレーム目
12フレーム目

 

13フレーム目で見た目には重複が解消されたように見えますが、Transformを見ると双方向への移動距離が0.96mなので、若干重なっています。

13フレーム目
13フレーム目

 

14フレーム目ではオブジェクトの間に隙間があるように見えます。移動距離も1.038となったので重複はしていなそうですが、『Scene』ビューで拡大してみたらちゃんと重複していました。

14フレーム目
14フレーム目

 

とても細かい部分ですが、黄色オブジェクトの領域を示すオレンジ色の線が、ピンク色オブジェクトの領域内にあるため、Colliderが微妙に重複しています。OnCollisionExit()は優秀ですね。

14フレーム目の重複
14フレーム目の重複

 

15フレーム目でついに重複が解消されました。

15フレーム目で解消
15フレーム目で解消

 

OnCollisionExit()ではデバッグ文を出力するようにしていたので、ちゃんとそれも観測できました。

デバッグ文も出た
デバッグ文も出た

 

実際に移動を開始したのが12フレーム目。そこから4フレーム目でColliderの重複が解消されたことに。

1フレームで解消されるもんだと思っていたので、案外時間かかっているなーというのが正直な感想です。3, 4フレームに対して「時間かかってる」ってのも変な話ですけどね。

人間の反応速度が10フレームくらいなんて話もありますし、「ん? 何かあったかな?」とギリ知覚できる程度ですね。

間違って壁の中でオブジェクトをインスタンス化しちゃった! なんて時の解消スピードが3, 4フレームになりそう、と言えそう(曖昧)

まとめ

とても細かい話ですが、Box Colliderが重複して配置された時、その重複が解消されるまでのフレーム数を観測してみました。

何の役に立つの? って聞かれたらいやもう本当に答えに窮するけど、たまにはこういう小ネタもいいよね。

アセット作ってます!

CTA-IMAGE

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

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

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