【Unity】Colliderを使って爆発的なぶっ飛び力を得る実験
Unityで衝突と言えばCollider。もはやUnity世界の常識レベルで大事なコンポーネントです。
今回はこのコンポーネントを使って、爆発的な力をオブジェクトに与える実験を行います。
ここ最近Colliderをいじって遊んでいた中で気付いたのですが、Collider同士を重ねると、Colliderが重ならない位置までオブジェクトが移動するんです。
これを応用して、AddForceを使わずにオブジェクトにぶっ飛び力を与えます。
環境
macOS 10.13 High Sierra
Unity2018.1.0f2
背景
Box Colliderのパラメータを紹介する記事を書いていたのですが、その中でColliderを使った遊びで、フレイザードの氷炎爆花散ごっこをしていたんです。
これらのCubeは、Colliderの大きさをメッシュより大きくして、お互いに重なるようにしています。Prefabからインスタンス化しただけで力を加えていなかったのですが、これだけ派手に吹き飛ぶのが楽しかったので、Collider同士の重なりでどの程度の力が生まれるのか気になって以下の実験をしました。
Colliderをアタッチしたオブジェクトを2つ使って斥力を確認したのですが、上記のGIFほどの勢いはありませんでした。
「2つでダメなら3つで試せばいいじゃない」とのお告げが降りてきたため、今回はオブジェクトの数を増やして確認してみます。
実験方法
実験方法は以下の通り。
- オブジェクトの占有領域が重複するようにシーンに3つ配置
- ゲーム開始時に排斥し合い、反対方向へ力が働くようにする
- Cubeの大きさは4とする
- 10mの高さから開始し、地面に落下した時のオブジェクト間の距離を測定
- 測定の対象は黄色とピンクの距離
- 距離が大きいほど斥力が大きく働いたとみなす
- 3つのオブジェクトにRigidbodyをアタッチする
氷炎爆花散の様子から、Colliderの重複を解消しようとする斥力によってオブジェクトが移動する先にさらにColliderがいれば、より遠くにオブジェクトを移動させようとするように見えます。
例えば黄色と青のCollider重複では、黄色は画像の左側に、青は画像の右側に移動させられます。しかし、青が移動した先にはまた別のColliderが。
今度は青とピンクが重ならない位置に移動しなくてはなりませんが、青が左側に行くと黄色とまたぶつかってしまいます。なので、今度は2つのオブジェクト間だけではなく黄色も含めて位置を計算することに。
黄色は青がいられるスペースを作るためにさらに左に移動させられます。結果として短いフレーム数でより長い距離を移動することになるので、速度が大きくなり、遠くへ飛ぶようになるはず。
実験結果
言葉で説明するより、実際にやってみる方が分かりやすいですね。
黄色、青、ピンクのPosition Xはそれぞれ0, 2, 4としています。
間に挟まれた青はそんなに飛んでいませんが、ピンクの勢いがすごいことになっています。
飛距離は95.172m。上の記事で、黄色とピンクの間隔を2mにした時には14.650mでした。6.5倍くらい?
あいだにColliderがいるだけで飛距離が一気に伸びますね。
Collider重複解消までのフレーム数
上の記事で、黄色とピンクの2つのオブジェクトでColliderの重複が解消されるまでの時間(フレーム数)を計測しました。
結果はRigidbodyがアタッチされてから4フレーム目での重複解消でした。
これに対してあいだに青を挟んだ場合を見てみましょ。
ゲーム開始直後は処理が立て込んでいるので、ゲーム開始から11フレーム目に3つのオブジェクトに対してRigidbodyをアタッチしています。画像はちょうどRigidbodyがアタッチされたフレーム。
次の12フレーム目になると、青のオブジェクトが他を押しのけているような感じ。黄色とピンクの移動距離は1.6mなので、青色がいないときに比べて2倍の移動距離となっています。
13フレーム目では黄色は既にColliderの重複が解消されました。Rigidbodyがアタッチされてから2フレーム目でこうなったので、青がいない時に比べて時間的にも早いです。
なお、後からRigidbodyをアタッチしているせいか、上のGIFと比べると、黄色とピンクの動きが逆になっていますね。GIFではピンクが先にぶっ飛んで行きましたが、ここでは黄色がぶっ飛んでいます。
スクリプトの実行順を指定していないので、Rigidbodyがアタッチされるタイミングも変わってるように見えます。
なお、Colliderが離れたことはOnTriggerExit()で検知しています。デバッグ文を入れておいたので、以下のように表示されました。出力は、自身のオブジェクト名 / 相手のオブジェクト名 としています。
黄色とピンクは面が接しているだけだったので、Rigidbodyのアタッチ後すぐ離れているのも納得。
黄色と青は2フレーム目で衝突解消。
青とピンクはRigidbodyアタッチ後の5フレーム目に離れています。
オブジェクトが2つだった場合に比べて、短時間かつ移動距離も長く、速度を計算するとかなり大きくなります。具体的な数字を使って速度を出して行くと泥沼にハマりそうなので避けますが、Colliderをいっぱい重ねれば大きな力を得られそう。
さらに増やす
こうなったらあとはどんどん増やすだけ。
オブジェクトを4つ重ねたらこんな感じ。あ、Collider自体を重ねるというよりは、Colliderの退避先を塞ぐイメージね。
計測対象は黄色と白。4つだと270.663mでした。
5個もやってみよー。
計測対象は黄色と赤。5つだと433.847mでした。
重なるColliderの数が増えれば増えるほど、大きな力が与えられます。この力によってオブジェクトの移動速度が大きくなり、結果として遠くまでぶっ飛んで行くようになります。
これくらいのオーダーのオブジェクト数なら多分AddForceを使った方が楽ですが、100個とか200個のオブジェクトをインスタンス化する場合は使えるかも。
特に冒頭の氷炎爆花散のように方向もランダムでいい時には、いちいちAddForceを呼ばずにColliderの性質を使うことでも爆発感を演出できます。
まとめ
Colliderを重複させて、それを解消する力を利用して爆発を表現する実験でした。Colliderの本来的な使い方ではないけど、演出のひとつとして使える……かも。
今回の実験から、Colliderの重複を解消しようとした時に、そのオブジェクトの退避先にColliderがいるとぶっ飛んで行くことが分かったので、Colliderの配置時はあまり重ねすぎない方がいいかも。
ゲーム開発の攻略チャートを作りました!
-
前の記事
ゲームでよく使われる「フレーム」って何のことを指してるの? 2018.05.25
-
次の記事
【Unity】狙った順に処理したい時はスクリプトの実行順を指定する 2018.05.27
コメントを書く