【Unity】重なっているColliderの斥力を観測する実験

【Unity】重なっているColliderの斥力を観測する実験

ColliderといえばUnityで衝突を扱う重要なコンポーネントです。

Colliderコンポーネントをアタッチされたオブジェクトが重なると、お互いの占有する領域外へと移動します。

この時、領域の重なり具合に応じて斥力(領域外への移動速度)がどの程度変わるのか実験してみます。

なおこの斥力という呼び方は私が勝手に言ってるだけなので悪しからず。

 

環境

macOS 10.13 High Sierra

Unity2018.1.0f2

背景

Box Colliderのパラメータを紹介する記事を書いていたのですが、その中でColliderを使った遊びで、フレイザードの氷炎爆花散ごっこをしました。

氷炎爆花散!
氷炎爆花散!

 

これらのCubeは、Colliderの大きさをメッシュより大きくして、お互いに重なるようにしています。Prefabからインスタンス化しただけで力を加えていなかったのですが、これだけ派手に吹き飛ぶのが楽しかったので、Collider同士の重なりでどの程度の力が生まれるのか気になって今回の実験に至りました。

実験方法

実験方法は以下の通り。

  • オブジェクトの占有領域が重複するようにシーンに配置
  • ゲーム開始時に排斥し合い、反対方向へ力が働くようにする
  • Cubeの大きさは4とする
  • 10mの高さから開始し、地面に落下した時のオブジェクト間の距離を測定
  • 距離が大きいほど斥力が大きく働いたとみなす
  • オブジェクト双方にRigidbodyをアタッチする
お互いに排斥し合う力を観察
お互いに排斥し合う力を観察

 

実験の様子は上記の画像の通り。ここでは例として、占有領域が25%重複したケースを画像として載せています。

ゲーム開始時に限定したのは、状況再現がしやすいためです。開始時の条件が一緒なら、ちゃんと同じ距離になるので実験にはもってこい。

 

実験するケース

まずは簡単に25%ずつ占有領域を変えてみます。

CubeのScaleはX, Y, Zとも4なので、Position Xを1ずつずらして確認します。

占有領域の重複 オブジェクトAのPosition X オブジェクトBのPosition X
0% 0 4
25% 0 3
50% 0 2
75% 0 1
100% 0 0

占有領域の重複0%

Colliderの占める領域が重複していないケースです。

地面到達時のオブジェクト間の距離は4.000m。

衝突がないので最初に配置したままの距離を維持しています。

占有領域の重複0%
占有領域の重複0%

 

占有領域の重複25%

ここからColliderの占有領域が重複し始めます。

地面到達時のオブジェクト間の距離は8.968m。

お互いに排斥している感じです。

占有領域の重複25%
占有領域の重複25%

 

占有領域の重複50%

地面到達時のオブジェクト間の距離は14.650m。

占有領域の重複が大きくなるにつれて斥力も大きくなりました。

占有領域の重複50%
占有領域の重複50%

 

占有領域の重複75%

地面到達時のオブジェクト間の距離は17.713m。

ここまでくるとだいぶ排斥してる感があります。

占有領域の重複75%
占有領域の重複75%

 

占有領域の重複100%

完全に重複している状態です。

地面到達時のオブジェクト間の距離は21.210m。

これまでと違って、X軸方向だけの運動ではなくなりました。

占有領域の重複100%
占有領域の重複100%

 

占有領域の重複と距離

上記の実験結果をまとめると以下のようになります。

占有領域の重複 距離の実測値(m) 配置時の距離を引いたもの(m)
0% 4.000 0
25% 8.968 5.968
50% 14.650 12.650
75% 17.713 16.713
100% 21.210 21.210

実測値から配置時のオブジェクト間の距離を引いたものが、斥力によって生じた力による距離とみなせそう。

一方がRigidbodyを持たない場合

上の実験では両方のオブジェクトがRigidbodyを持っていましたが、一方がRigidbodyを持たないStaticなColliderである場合はどうでしょうか。

実験の条件は上のものとほぼ同じですが、黄色いオブジェクトのRigidbodyを外して実験します。

距離の測定は、(0f, 2f, 0f)の位置からとします。衝突がないときに黄色いオブジェクトが落下する位置なので、ここから測定するようにしましょ。

Static : 占有領域の重複0%

距離は4.000mです。

衝突が起こらないので最初の距離が保たれます……って上でも同じようなこと言いましたね。

一方がStaticで占有領域の重複0%
一方がStaticで占有領域の重複0%

 

Static : 占有領域の重複25%

距離は9.044mです。

25%の重複だとぺいっと押し出されます。

一方がStaticで占有領域の重複25%
一方がStaticで占有領域の重複25%

 

Static : 占有領域の重複50%

距離は14.796mです。

25%に比べて勢いを増しています。

一方がStaticで占有領域の重複50%
一方がStaticで占有領域の重複50%

 

Static : 占有領域の重複75%

距離は17.365mです。

回転の方向も若干変わっているような気がします。

一方がStaticで占有領域の重複75%
一方がStaticで占有領域の重複75%

 

Static : 占有領域の重複100%

距離は27.154mです。

結構派手に飛びますね。

一方がStaticで占有領域の重複100%
一方がStaticで占有領域の重複100%

 

一方がStaticのケースにおける占有領域の重複と距離

上記の実験結果をまとめると以下のようになります。

占有領域の重複 距離の実測値(m) Static/配置時の距離を引いたもの(m) Dynamic/配置時の距離を引いたもの(m)
0% 4.000 0 0
25% 9.044 6.044 5.968
50% 14.796 12.796 12.650
75% 17.365 16.365 16.713
100% 27.154 27.154 21.210

 

Staticの場合と、双方がRigidbodyを持つ(Dynamicの)場合を比較すると、だいたい同じ傾向ですね。

Cubeであることから、回転によって地面に到達するタイミングが若干変わりますが、100%のケース以外は似たような位置に落下しました。

100%のケースは何だかすごく飛んでいますが……何でしょうね?(無知)

押し出される方向も+X軸方向ですし、0以上だったら+X軸方向に描画、とか決まってる感じかな。いかんせんUnityEngineのスクリプトは中身を見れないので動きから予想するしかないのよね。

結果から言えそうなことは、Colliderの位置が重複すると、重複していない状態に戻すためにオブジェクトを1フレーム(または数フレーム)のうちにColliderが重複しない場所まで移動させます。

その移動距離が長くなるほど、重複状態が解除された後の斥力(移動速度)が大きくなるため、遠くに飛びます。

1フレームあたりの移動距離が長い=速度が大きいってことですもんね。

まとめ

Colliderの斥力を使った実験を行いました。

やる前からだいたいの予想は付いていたかと思いますが、重複している領域が大きいほど、大きな斥力が発生します。

完全に同じ位置にいる場合は、「多分各軸の+方向に飛ぶ」くらいの認識でいるのがいいのかしら。

アセット作ってます!

CTA-IMAGE

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

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

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