この記事でのバージョン
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では使えません。