Unity で OnCollisonEnter か OnTriggerEnter が呼ばれないと困っている人もいるかと思い、イベントを呼ぶための Rigidbody と IsTrigger の関係を表に整理しました。
Cube と Sphere を衝突させて、イベントが起こる起こらないを確認しています。
TL;DR
Unity で OnCollisonEnter か OnTriggerEnter を呼ぶためには、まず、
- 衝突しあう両方のオブジェクトに Collider を入れる
- 衝突するどちらか一方に Rigidbody を入れる
です。
その上で Collider の
- IsTrigger が Off なら OnCollisionEnter が呼ばれます。
- IsTrigger が On なら OnTriggerEnter が呼ばれます。
表のまとめ
Collider は必須
ぶつかり合う Cube と Sphere の 両方
に Collider が入っていないと、イベントは起きません。
Rigidbody はどちらかに入っていれば反応します。
IsTrigger が優先
さっきの表をよくよく見ると、ある法則があり、青、緑、ピンクで塗ったセルの塊ごとに結果は同じ。
つまり IsTrigger が On か Off に影響され、On ときは OnTriggerEnter が呼ばれます。
それでは説明です
確認した環境
Unity のバージョンは 2019.1.6f1 で、こんな感じの簡単な環境で実施しています。
Code sample
Sphere.cs
using UnityEngine;
public class Sphere : MonoBehaviour
{
private void OnCollisionEnter(Collision other)
{
Debug.Log($"{other.transform.name} is OnCollisionEnter in Sphere.");
}
private void OnTriggerEnter(Collider other)
{
Debug.Log($"{other.transform.name} is OnTriggerEnter in Sphere.");
}
}
Cube.cs
using UnityEngine;
public class Cube : MonoBehaviour
{
private float speed = 0.1f;
private float elapsed = 0.0f;
// 適当に動かしてぶつけることにした
void Update()
{
elapsed += Time.deltaTime;
var pos = transform.position;
transform.position = new Vector3(pos.x + speed, pos.y, pos.z);
if (elapsed > 1.0f)
{
speed = -speed;
elapsed = 0.0f;
}
}
private void OnCollisionEnter(Collision other)
{
Debug.Log($"{other.transform.name} is OnCollisionEnter in Cube.");
}
private void OnTriggerEnter(Collider other)
{
Debug.Log($"{other.transform.name} is OnTriggerEnter in Cube.");
}
}
確認した内容
Rigidbody のある・なし、IsTrigger の On・Off を切り替えて、コンソールに出力されるログを確認しました。
Rigidbody のある・なし
左側の Cube には Rigidbody がなく、右側の Sphere にはRigidbody がある状態です。
IsTrigger のOn・Off
左側の Cube の Box Collider の IsTrigger は Off で、右側の Sphere Sphere Collider の IsTrigger は On です。
補足
- 発火する条件を満たしていれば、OnTriggerEnter・OnCollisonEnter は、 Cube・Sphere のどちらに書いても、両方に書いても、処理が走ります。
- Console に Debug.Log が表示されないと思ってこの結果が間違っていると思うかもしれませんが、実は Console にデバッグレベルのログが表示されない設定になっているかもしれません。お気を付けください。