【Unity】Unityのイベント関数を理解する - OnTriggerとOnCollisionの違い

作成: 2025-12-07最終更新: 2026-07-13

オブジェクト同士の接触を検知するOnTriggerEnterとOnCollisionEnter。これらのイベント関数がいつ、どのように呼び出されるのか、その違いと正しい使い分けを初心者向けに解説します。

「アイテムに触れたら取得」「弾が当たったらダメージ」「エリアに入ったらイベント発生」——ゲームのインタラクションの多くは「何かが何かに触れた」瞬間から始まります。この検知を担うのがOnCollisionEnterOnTriggerEnterですが、 どちらを使えばいいのか で最初は必ず迷います。

判断基準はシンプルで、 ぶつかって跳ね返ってほしいならCollision、すり抜けて検知だけしたいならTrigger です。この記事では両者の違いと使い方、そして「イベントが発生しない!」となったときのチェックポイントまで解説します。

接触イベントのイメージ。物理的にぶつかる衝突と、領域をすり抜けて検知するトリガー

この記事でわかること

  • CollisionとTriggerの違いと使い分けの基準
  • Enter / Stay / Exitそれぞれの呼ばれるタイミング
  • イベントが発生するための条件(Rigidbodyの必要性)
  • 衝突相手の情報(Collision / Collider)の使い方

Sponsored

物理イベント vs トリガーイベント

Unityの接触イベントは、大きく分けて2種類あります。

  1. 物理イベント (Collision): オブジェクト同士が物理的に「衝突」したときに発生します。現実世界の衝突のように、オブジェクトは互いに跳ね返ったり、押し合ったりします。OnCollision系の関数が対応します。
  2. トリガーイベント (Trigger): オブジェクトが特定の「領域」に侵入または退出したときに発生します。オブジェクトは互いにすり抜け、物理的な影響を与えません。OnTrigger系の関数が対応します。
CollisionとTriggerの違いの比較図。Collisionはボールが壁にぶつかって跳ね返り衝突イベントが発生する。Triggerは半透明の領域をすり抜けながら侵入イベントが発生する

どちらのイベントを使うかは、実装したい挙動によって決まります。

  • 壁や地面との衝突、ビリヤードの玉同士の衝突など、 物理的な反発が必要な場合Collision を使います。
  • アイテムの取得ゾーン、イベント発生エリア、ワープゾーンなど、 物理的な反発が不要で、領域への出入りだけを検知したい場合Trigger を使います。

Collisionイベントの使い方

Collisionイベントは、OnCollisionEnter, OnCollisionStay, OnCollisionExitの3種類があります。

イベント関数呼び出されるタイミング
OnCollisionEnter(Collision other)他のColliderとの衝突が始まった瞬間に1回だけ呼ばれる。
OnCollisionStay(Collision other)他のColliderと接触している間、物理更新のたびに呼ばれ続ける。
OnCollisionExit(Collision other)他のColliderから離れた瞬間に1回だけ呼ばれる。

補足: Stay系の「呼ばれ続ける」は、正確には 描画の毎フレームではなく、物理更新(FixedUpdateと同じタイミング)に合わせて です。フレームレートが物理更新より高い環境では「Stayが呼ばれない描画フレーム」も存在します。継続ダメージなどの時間計算にはTime.deltaTimeではなくTime.fixedDeltaTimeが対応する点も覚えておくと混乱しません。

これらの関数は、引数としてCollisionクラスのインスタンスを受け取ります。このotherオブジェクトには、衝突に関する様々な情報(衝突相手のオブジェクト、衝突した位置、法線ベクトルなど)が含まれています。

using UnityEngine;

public class CollisionDetector : MonoBehaviour
{
    // 他のオブジェクトと衝突した瞬間に呼ばれる
    void OnCollisionEnter(Collision collision)
    {
        // collision.gameObjectで衝突相手のゲームオブジェクトにアクセスできる
        Debug.Log(collision.gameObject.name + " と衝突しました!");

        // 相手のタグが"Enemy"なら、自分自身を破壊する
        if (collision.gameObject.CompareTag("Enemy"))
        {
            Destroy(gameObject);
        }
    }
}

Collisionイベントの発生条件

  • 衝突する両方のオブジェクトがColliderコンポーネントを持っている。
  • 衝突するオブジェクトの少なくとも一方Rigidbodyコンポーネントを持っている。
Sponsored

Triggerイベントの使い方

Triggerイベントを利用するには、まずColliderコンポーネントのIs Triggerプロパティにチェックを入れる必要があります。これにより、そのColliderは物理的な形状ではなく、イベントを発生させるための「領域」として扱われるようになります。

Triggerイベントも3種類あります。

イベント関数呼び出されるタイミング
OnTriggerEnter(Collider other)他のColliderがトリガー領域に侵入した瞬間に1回だけ呼ばれる。
OnTriggerStay(Collider other)他のColliderがトリガー領域に留まっている間、物理更新のたびに呼ばれ続ける。
OnTriggerExit(Collider other)他のColliderがトリガー領域から退出した瞬間に1回だけ呼ばれる。

Enter・Stay・Exitの関係は「入った瞬間・いる間・出た瞬間」です。キャラクターが領域を通過する流れで見ると分かりやすいでしょう(Collision系も同じ関係です)。

Enter・Stay・Exitのタイミングを表す図。キャラクターが領域に入った瞬間にEnter、領域内にいる間は物理更新ごとにStay、出た瞬間にExitが呼ばれる

実際のゲーム開発では、この3つをこう使い分けるのが定番です。「一度きりの出来事はEnter/Exit、続いている状態への反応はStay」と覚えておくと、どこに処理を書くべきかがすぐ判断できます。

Enter・Stay・Exitの実例。Enterはコインの取得(触れた瞬間に1回)、Stayは毒沼での継続ダメージ(いる間ずっと)、Exitはセーフエリアからの退出検知(出た瞬間に1回)

こちらの関数は、引数としてColliderクラスのインスタンスを受け取ります。otherには、領域に侵入してきた相手のColliderコンポーネントが渡されます。

using UnityEngine;

public class ItemCollector : MonoBehaviour
{
    // 他のColliderがトリガー領域に侵入した瞬間に呼ばれる
    void OnTriggerEnter(Collider other)
    {
        // other.gameObjectで侵入してきた相手のゲームオブジェクトにアクセスできる
        Debug.Log(other.gameObject.name + " がアイテムゾーンに入りました。");

        // 相手が"Player"タグを持っていたら、アイテム(自分自身)を非表示にする
        if (other.CompareTag("Player"))
        {
            Debug.Log("アイテムを獲得!");
            gameObject.SetActive(false);
        }
    }
}

Triggerイベントの発生条件

  • イベントを発生させる両方のオブジェクトがColliderコンポーネントを持っている。
  • 少なくとも一方のオブジェクトがRigidbodyコンポーネントを持っている。
  • 少なくとも一方のオブジェクトのColliderでIs Triggerが有効になっている。

補足: 「イベントが呼ばれない!」というときの原因は、ほぼRigidbodyの付け忘れです。CollisionもTriggerも、 少なくとも一方にRigidbodyが必要 という条件は共通です。

ただし、Rigidbodyの状態によって発生するイベントは変わります。「とりあえずKinematicを付ければ解決」ではない点に注意して、次の組み合わせを確認してください。

状況CollisionイベントTriggerイベント
一方が通常のRigidbody✅ 発生する✅ 発生する
一方がKinematicなRigidbody(相手はColliderのみ)❌ 発生しない✅ 発生する
Kinematic同士❌ 発生しない✅ 発生する
Layer Collision Matrixで衝突を切った組み合わせ❌ 発生しない❌ 発生しない
  • 検知ゾーン(Trigger)側にKinematicなRigidbodyを付ける のは、物理挙動を持たせずに条件を満たす定番の使い方です。
  • 一方、 物理的な衝突(Collision)を検知したいのにKinematic同士 になっていると、イベントは発生しません。少なくとも一方は通常のRigidbodyにします。
  • Layer Collision Matrix で衝突自体を切っているレイヤー同士は、どちらのイベントも発生しません。「条件は全部満たしているのに呼ばれない」ときはここを疑いましょう。
  • 高速で動く弾がすり抜ける場合は、RigidbodyのCollision DetectionContinuous系に変更します。
接触イベントの発生条件のまとめ図。両方にCollider、少なくとも一方にRigidbodyが必要で、TriggerにはさらにIs Triggerのチェックが必要

その他のイベント関数

Unityには、物理イベント以外にも様々なイベント関数が用意されています。例えば、マウスカーソルがオブジェクトのCollider上にあるかどうかを検知するマウスイベントなどがあります。

  • OnMouseEnter(): マウスカーソルがColliderの上に乗った瞬間。
  • OnMouseExit(): マウスカーソルがColliderの上から離れた瞬間。
  • OnMouseDown(): Collider上でマウスボタンが押された瞬間。

これらは、シーン内の3Dオブジェクトをクリックして選択するような機能を実装する際に便利です。

注意: OnMouse系はColliderを持つオブジェクト専用で、 uGUIのボタンやパネルの操作には使いません 。UIのクリックはEventSystem経由(ButtononClickなど)が担当します(詳しくは Buttonイベントの記事 へ)。また、OnMouse系は旧Input Systemに依存しているため、Project SettingsのActive Input Handlingを「Input System Package (New)」のみに設定していると動作しません。New Input Systemを使うプロジェクトでは、クリック判定はRaycastなど別の方法で実装します。

おまけ:先に知っておくと良いこと

接触イベントを使いこなせるようになったら、次のステップはこのあたりです。

  • 「敵とだけ衝突したい」はレイヤーで制御: タグでif分岐する前に、そもそも不要な組み合わせはLayer Collision Matrixで衝突自体を切れます。レイヤーとタグの記事 で解説しています。
  • 触れる前に「見る」ならRaycast: 「銃の照準の先に敵がいるか」のような接触前の判定は Raycast の出番です。Physics.Raycastの記事 でマスターできます。
  • 2Dゲームでは関数名に2Dが付く: 2D物理ではOnCollisionEnter2D(Collision2D)/OnTriggerEnter2D(Collider2D)と、 関数名も引数の型も2D版 になります(3D用の関数は呼ばれません)。2D物理の記事 が参考になります。

まとめ

接触イベントは、ゲームにインタラクティブ性をもたらすための基本です。OnCollisionOnTriggerの違いを正しく理解し、目的に応じて使い分けましょう。

  • 物理的な反発が必要なら → Collision (Is Triggerはオフ)。
  • 領域への出入りだけを検知したい(すり抜けさせたい)なら → Trigger (Is Triggerはオン)。
  • どちらのイベントも、少なくとも一方のオブジェクトにはRigidbodyが必要です。

これらのイベント関数をマスターして、プレイヤーのアクションに豊かに反応する、生き生きとしたゲーム世界を創造しましょう。