(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]


本ブログの運営者kan.kikuchiが個人で開発したゲームです!

    

全ての衝突を一度に取得し、一括で処理出来る Contact Event【Unity】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 2022.2.8f1


はじめに

UnityではOnCollisionEnter等、衝突の検知が出来るコールバックがありますが、

//衝突した時に実行される
private void OnCollisionEnter(Collision collision) {}


これらは各オブジェクトごと及び各衝突ごとに実行されるため、大量に発生すると重くなりがちです。


しかしUnity 2022.2から全ての衝突を一度に取得し、一括で処理出来るようになりました!


という事で今回は、それを試してみた感じの記事です。


なお、記事中の画像は以下のアセットを使っております。

Mobile Garage Vol. 2



全ての衝突を一度に取得し、一括で処理出来る Contact Event

全ての衝突を一度に取得し、一括で処理するにはContact Eventを使います。



使い方は以下のような感じにイベントに処理を設定するだけ。

//オブジェクトが有効になったらイベントに処理を登録
private void OnEnable() {
  Physics.ContactEvent += OnContact;
}
  
//オブジェクトが無効になったらイベントに処理を削除
private void OnDisable() {
  Physics.ContactEvent -= OnContact;
}
  
//全ての衝突を一度に取得し、一括で処理
private void OnContact(PhysicsScene scene, NativeArray<ContactPairHeader>.ReadOnly headers) {
  foreach (var header in headers) {
    for (int i = 0; i < header.PairCount; i++) {
      var contactPair = header.GetContactPair(i);
      Debug.Log($"{contactPair.Collider.name}{contactPair.OtherCollider.name}が衝突");
    }
  }
}


なお、衝突を取得したいコライダーのProvides Contactsを有効にしておく必要があります。


ただし、OnCollisionEnter等のコールバックを他のスクリプトで実装している場合

Provides Contactsが無効でもContactEvent側のコールバックも実行されます。

(両方のコールバックが実行される感じ)


ちなみにContact Eventでまとめて処理したらどの程度軽くなるかの検証は以下の動画を参考の事。

Unity の物理エンジン最新機能を紹介! 2022.2 Physics アップデート - YouTube


余談ですが、OnTriggerEnterなどのTrigger系のコールバックやPhysics2Dでは使えません。