はじめてCollider 2Dコンポーネントを利用して、衝突判定した際に色々悩んだ記憶があるので、自身の知識の整理も兼ねてまとめておきます。以下の章に大別して書いています。
- 「Collider 2Dについて」
- 「物体の移動方法について」
- 「衝突判定について」
今回は、単純な衝突判定のみを取り扱うので、以下については触れません。機会があれば、別の記事として書こうと思います。
- 「Composite Collider 2D」は今回取り扱いません。複数のColliderが重なった時に、それらのCompositeを合成するものです。
- Colliderの「Used By Effector」などのパラメータとそれに関する事柄についても取り扱いません。
Collider 2Dについて
Collider 2Dとその種類
GameObjectに Collider 2Dコンポーネント をアタッチすることで、そのGameObjectにいわゆる「当たり判定」が付与できます。
Collider 2Dは、形状別に用意されています。それぞれのColliderは、基本的に「形状 + Collider 2D」という名前がつけられています。緑枠の部分が Collider の「当たり判定」の部分です。
色々ありますが形状や用途に合ったColliderを選択すれば良いです。複雑な形状のColliderを作りたい場合は、Edge Collider 2D もしくは Polygon Collider 2D が適切かと思います。GameObjectにアタッチされたColliderは、「Edit Collider」ボタンを押すことで編集できます。
Colliderは複数アタッチできます。たとえば次のように「Box Collider 2D」と「Capsule Collider 2D」をそれぞれアタッチしておくこともできます。
物理シミュレーションの有効化
Colliderの振る舞いを有効にするためには、GameObjectの Physics Simulation が有効になっていなければいけません。GameObjectに、RigidBody 2D をアタッチし、BodyTypeをDynamicとし、simulated パラメータをONにすることで Physics Simulation が有効になります。
「当たり判定」を有効にするには、Collider 2D と RigidBody 2D の2つのコンポーネントのアタッチ、そして、RigidBody 2Dの simulated パラメータをONにする必要があります。
衝突判定について
is Trigger パラメータについて
Collider 2Dがアタッチされたオブジェクト同士が接触すると、デフォルトでは 衝突する 挙動を示します。Collider の is Trigger にチェックを入れると、そのオブジェクトは 衝突せずにすりぬける ようになります。後者は、Colliderを領域とみなし、その領域に対する接触判定と考えるとわかりやすいと思います。私はこれを衝突に対して、 「侵入」 と呼んでいます。
イベント発生時のコールバック
「衝突」もしくは「侵入」を検知した際に、専用のコールバックメソッドが呼び出されます。これらのコールバックメソッドをオーバーライドすることで、衝突・侵入時の処理を記載します。このコールバックは、双方のGameObjectで呼び出されます。
また、Aの is Trigger=ON、Bの is Trigger=OFFとした場合、2つのオブジェクトは衝突せずに侵入します。侵入した際に双方のオブジェクトで OnTriggerEnter2D が呼び出されます。ここで重要なのは、 is Triggerにチェックを入れていないBのコールバックも呼ばれる ということです。
コールバックの種類
検知したイベントに応じて、Enter2D, Stay2D, Exit2D がつくメソッドが呼びだされるようになっています。
衝突時のメソッド | 発生条件 |
---|---|
OnCollisionEnter2D | Colliderを持つオブジェクト同士が衝突した時 |
OnCollisionStay2D | Colliderを持つオブジェクトが接し続けている間、毎フレーム |
OnCollisionExit2D | 接触状態にあるColliderを持つオブジェクト同士が離れた時 |
侵入時のメソッド | 発生条件 |
---|---|
OnTriggerEnter2D | Colliderを持つオブジェクトの領域に入った時 |
OnTriggerStay2D | Colliderを持つオブジェクトの領域に入っている時 |
OnTriggerExit2D | Colliderを持つオブジェクトの領域から出た時 |
具体例
上記メソッドをオーバーライドして、GameObjectに衝突・侵入時の処理を追加します。例では、衝突・侵入したオブジェクトの名前をログとして表示しています。引数には衝突・侵入したオブジェクトが渡されます。
public class Sample : MonoBehaviour { void OnTriggerEnter2D(Collider2D other) { Debug.Log("OnTriggerEnter2D: " + other.gameObject.name); } void OnTriggerStay2D(Collider2D other) { Debug.Log("OnTriggerStay2D: " + other.gameObject.name); } void OnTriggerExit2D(Collider2D other) { Debug.Log("OnTriggerExit2D: " + other.gameObject.name); } void OnCollisionEnter2D(Collision2D collision) { Debug.Log("OnCollisionEnter2D: " + collision.gameObject.name); } void OnCollisionStay2D(Collision2D collision) { Debug.Log("OnCollisionStay2D: " + collision.gameObject.name); } void OnCollisionExit2D(Collision2D collision) { Debug.Log("OnCollisionExit2D: " + collision.gameObject.name); } }
コンポーネントとコールバックを "2D" で合わせる
2D用のRigidBody、Colliderとそれに関するコールバックすべてに 2D がついていることを確認してください。2Dがついていないものは3D用のコンポーネントです。2Dと3Dで異なるコンポーネントとして用意されています。2Dもしくは3Dで統一していないと動作しません。
さいごに
以上、Collider 2D を用いた衝突判定のもっとも基本的(と思われる)な部分について記載しました。+αの内容は別の記事にまとめていこうと思います。何か間違い等あれば、ぜひコメントいただければと思います。
Polygon Collider 2Dで利用しているSpriteや、衝突・侵入判定の図で利用しているSpriteは以下のAssetを利用しています。プロトタイプを作る際などに便利なのでぜひぜひ。