今まで何となく使っていたOnCollisionとOnTriggerですが、どういう設定をした時にこのイベントが呼ばれているんでしょうか?
個人的にはコライダの設定で
Is Triggerのチェックを入れるとスクリプトから操作し、キャラクターの進入等を検知し、
Is Triggerのチェックを外すと他のコライダを持つ物体と衝突判定をするようになる。
という感じなので、そういった場面で使っています。
Is Triggerのチェックが入っていればOnTrigger系
Is Triggerのチェックが入っていなければOnCollision系
としています。
OnCollisionとOnTriggerの違いを確認する
わたくしの適当な使い分けではわかりませんので、
実際にどういう設定の時にイベントが呼ばれるか確認してみます。
まずはヒエラルキー上にCapsule(CharactereController用)とCubeをいくつか作成します。
CharacterController以外はCubeの名前を変更して作成します。
CollisionはBox ColliderのIs Triggerのチェックを外します。
TriggerはBox ColliderのIs Triggerにチェックを入れます。
CharacterControllerはCharacterControllerを取り付けます。
CollisionRigidbodyNonKineはBox Colliderのチェックを外し、Rigidbodyを取り付けIs Kinematicのチェックを外します。
CollisionRigidbodyKineはBox Colliderのチェックを外し、Rigidbodyを取り付けIs Kinematicのチェックをします。
TriggerRigidbodyNonKineはBox Colliderのチェックをし、Rigidbodyを取り付けIs Kinematicのチェックを外します。
TriggerRigidbodyKineはBox Colliderのチェックをし、Rigidbodyを取り付けIs Kinematicのチェックをします。
それぞれのゲームオブジェクトにCollisionTriggerTestという新しいスクリプトを設定して、下記のように記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using UnityEngine; using System.Collections; public class CollisionTriggerTest : MonoBehaviour { void OnTriggerEnter(Collider col) { Debug.Log(gameObject.name + " : " + "Trigger"); } void OnCollisionEnter(Collision col) { Debug.Log(gameObject.name + " : " + "Collision"); } void OnControllerColliderHit(ControllerColliderHit col) { Debug.Log(gameObject.name + " : " + "ControllerColliderHit"); } } |
イベント受け取り関数を記述し、何らかと接触しイベントを受け取ったら、自分自身の名前とどのイベントが発生したかを表示します。
これでサンプルが出来上がりました。
接触イベントを表にまとめました
先ほど作ったサンプルを使ってイベントの検証をした結果を表にしてみました。
縦が接触させる側で、横が接触される側。
接触された側で発生するイベントを表記してあります。(接触させる側でも同じイベントが発生します・・・)
Collision・・・コライダのIs Triggerのチェックを外したもの
Trigger・・・コライダのIs Triggerにチェックを入れたもの
CharacterController・・・CharacterControllerを取りつけたCapsule
CollisionRigidbodyNonKine・・・コライダのIs Triggerのチェックを外し、Rigidbodyを取りつけIs Kinematicのチェックを外したもの
CollisionRigidbodyKine・・・コライダのIs Triggerのチェックを外し、Rigidbodyを取りつけIs Kinematicのチェックを入れたもの
TriggerRigidbodyNonKine・・・コライダのIs Triggerにチェックを入れ、Rigidbodyを取りつけIs Kinematicのチェックを外したもの
TriggerRigidbodyKine・・・コライダのIs Triggerのチェックを入れ、Rigidbodyを取りつけIs Kinematicのチェックを入れたもの
Collision | Trigger | CharacterController | CollisionRigidbodyNonKine | CollisionRigidbodyKine | TriggerRigidbodyNonKine | TriggerRigidbodyKine | |
Collision | – | – | – | – | – | Trigger | Trigger |
Trigger | – | – | Trigger | Trigger | Trigger | Trigger | Trigger |
CharacterController | – | Trigger | – | – | – | Trigger | Trigger |
CollisionRigidbodyNonKine | Collision | Trigger | Collision | Collision | Collision | Trigger | Trigger |
CollisionRigidbodyKine | – | Trigger | – | Collision | – | Trigger | Trigger |
TriggerRigidbodyNonKine | Trigger | Trigger | Trigger | Trigger | Trigger | Trigger | Trigger |
TriggerRigidbodyKine | Trigger | Trigger | Trigger | Trigger | Trigger | Trigger | Trigger |
CharacterControllerを取りつけたブロックを手動で動かして検証した結果を載せていましたが、ゲーム内でスクリプトを使ってキャラクターを動かして検証したところ
こちらも相手方も検知出来ない部分(Collisionが発生しない)があったので修正しました。
CharacterControllerをシーンビューで動かして衝突させるとCollisionが発生しましたが、使い方としては違うのでCollisionは発生しないと考えた方がいいかもしれません(表では発生しない事にしてあります)。
主に使うと思われるCharacterControllerで動かすキャラクター(Chara)と他のゲームオブジェクトを判定する場合を考えると相手方を何にするか決める事が出来ます。
検知エリアの場合はTrigger、つまりコライダのIs Triggerにチェックを入れたものを使えばいいことになります。
CharacterControllerで動かすキャラクターの場合はCollisionはこちらも相手も検知出来ず、Triggerでは相手方のIs Triggerにチェックが入っている時だけOnTrigger系で検知出来ます。
CharacterControllerのキャラクターの場合はOnControllerColliderHitというメソッドで相手方を検知する事が出来るのでこのメソッドを使用するといいと思います。
Rigidbodyとコライダを使ってキャラクターを動かす方法は
の記事で取り扱っていますが、
キャラクターはIs Triggerのチェックを外し、RigidbodyのIs Kinematicのチェックを外したCollisionRigidbodyNonKineになります。
Rigidbody+コライダでキャラクターを動かす時はTrigger、Collisionの検知も出来るので非常に便利です。