Unityの物理演算と衝突判定:OnCollisionEnterとOnTriggerEnterの違いを学ぶ(初級編)

Unityは、初心者からプロフェッショナルまで幅広いユーザーが利用するゲームエンジンです。ゲーム開発において、物理演算と衝突判定はとても重要な要素です。

この記事では、Unityの物理演算の基礎から、衝突判定のイベントである OnCollisionEnterOnTriggerEnter の違いについて解説します。さらに、学んだ内容をもとに、演習問題とその解答例もご紹介します。

これからUnityでの開発を始める方や、物理演算に興味がある方にとって、分かりやすい初級編としてご活用いただければ幸いです。


衝突判定の基本

Unityでは、衝突判定を行うために「物理エンジン」が活用されています。衝突判定は大きく分けて2種類あります。

  1. 物理的な衝突(Collision)
    物体同士が実際にぶつかったときに発生するイベントです。オブジェクトが互いに物理的な影響を及ぼし合うため、反発力や摩擦などのシミュレーションが行われます。
  2. トリガーによる判定(Trigger)
    物体が衝突エリアに入ったことを検知するためのイベントです。オブジェクト同士の物理的な反発は発生せず、エリア内に入ったことをプログラム上で検知したい場合に使用します。

この2つは、Unityの物理挙動の中で重要な役割を果たしますが、それぞれ用途が異なります。次のセクションで具体的なイベントメソッドの使い方について解説します。


OnCollisionEnterの使い方

概要

OnCollisionEnter は、ColliderとRigidbodyを持つオブジェクト同士が実際に衝突したときに呼び出されるイベントです。

衝突時に発生する物理的な力を計算するため、オブジェクト同士がぶつかった瞬間に詳細な情報を取得することができます。

必要な設定

  • Rigidbodyコンポーネント
    衝突するオブジェクトの少なくとも一方にRigidbodyが必要です。
  • Colliderコンポーネント
    両方のオブジェクトにColliderが設定されている必要があります。

コード例

using UnityEngine;

public class CollisionExample : MonoBehaviour
{
    // オブジェクトが他のオブジェクトと衝突したときに呼び出される
    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log("衝突しました: " + collision.gameObject.name);
        // 衝突したオブジェクトの情報を利用して、処理を追加することができます
    }
}

上記のコードでは、衝突が発生すると、どのオブジェクトと衝突したのかがコンソールに表示されます。これにより、デバッグやイベント処理が容易になります。


OnTriggerEnterの使い方

概要

OnTriggerEnter は、Colliderの「Is Trigger」プロパティが有効になっている場合に使用されるイベントです。

物理的な衝突ではなく、オブジェクトがトリガー領域に入ったかどうかを検知するために利用されます。衝突時の物理演算が発生しないため、主に判定用のエリアや、イベントの発生タイミングを検知する際に役立ちます。

必要な設定

  • Colliderコンポーネント
    トリガーとして利用するオブジェクトのColliderの「Is Trigger」にチェックを入れます。
  • Rigidbodyコンポーネント
    通常は、衝突する側のオブジェクトにRigidbodyが必要ですが、トリガー側は必ずしも必要ありません。

コード例

using UnityEngine;

public class TriggerExample : MonoBehaviour
{
    // オブジェクトがトリガーエリアに入ったときに呼び出される
    private void OnTriggerEnter(Collider other)
    {
        Debug.Log("トリガーに入りました: " + other.gameObject.name);
        // エリアに入ったオブジェクトの情報を利用して、処理を追加することができます
    }
}

このコードは、指定したエリアにオブジェクトが入った際に呼び出され、どのオブジェクトがトリガー領域に入ったかを判定してログに出力します。


OnCollisionEnter と OnTriggerEnter の違い

主な違い

項目OnCollisionEnterOnTriggerEnter
物理演算の有無実際の物理演算(反発、摩擦、力の伝播など)を伴うため、オブジェクト同士がぶつかったときの力の計算が行われる物理的な反発や力の計算は行われず、判定専用に利用される
使用シーンプレイヤーと敵の衝突、弾丸の当たり判定など、物理的なインタラクションが必要な場合に用いられるゾーンに入ったときのイベント(例:アイテムを取得した時のエフェクト、次のエリアへの移動トリガーなど)でよく使われる
必要なコンポーネント衝突する両方のオブジェクトにColliderが必要であり、少なくとも一方にRigidbodyが設定されている必要があるトリガーとして設定するオブジェクトのColliderの「Is Trigger」を有効にするだけで、物理演算は行われない

注意点

  • パフォーマンス面
    衝突判定は頻繁に発生する可能性があるため、処理内容は軽量にする必要があります。無駄な計算や重い処理をOnCollisionEnterやOnTriggerEnter内で行うと、ゲーム全体のパフォーマンスに影響を及ぼす可能性があります。
  • デバッグ
    開発中は、デバッグログを活用して実際にどのタイミングでイベントが発生しているかを確認すると良いでしょう。

実際のシーンでの応用例

シナリオ1:プレイヤーと敵の衝突

プレイヤーが敵と衝突すると、体力が減少するようなゲームを考えます。この場合、物理的な衝突が発生するため、OnCollisionEnterを利用します。

プレイヤーと敵の両方にColliderが設定され、プレイヤーにRigidbodyを追加しておけば、衝突が発生したタイミングでイベント処理が実行されます。

シナリオ2:エリアへの侵入検知

特定のエリアにプレイヤーが入ると、次のステージに移動するトリガーイベントを発生させる場合は、OnTriggerEnterを利用します。

エリアを示すオブジェクトのColliderに「Is Trigger」をチェックし、プレイヤーが入った瞬間にイベントが発生するように設定します。


まとめ

Unityの物理演算と衝突判定は、ゲーム開発において非常に重要な要素です。

  • OnCollisionEnter は、実際にオブジェクトが衝突した際に物理的な力の計算とともにイベントが発生します。
  • OnTriggerEnter は、オブジェクトが指定したエリアに入ったかどうかを判定するためのイベントであり、物理的な反発は発生しません。

それぞれの特性を理解することで、より効果的なゲームロジックの実装が可能となります。初心者の方は、まずはシンプルなシーンで基本的な衝突判定を実装し、デバッグを通して動作を確認することから始めると良いでしょう。


演習問題と解答例

演習問題1

問題

Unityで、以下の条件を満たすスクリプトを作成してください。

  1. プレイヤーオブジェクトが敵オブジェクトに物理的に衝突した場合(OnCollisionEnterを使用)、コンソールに「プレイヤーが敵に衝突」と表示する。
  2. プレイヤーオブジェクトが特定のエリア(トリガー)に入った場合(OnTriggerEnterを使用)、コンソールに「プレイヤーがエリアに侵入」と表示する。
  3. それぞれのイベントが正しく動作するために必要なコンポーネントの設定方法も簡潔に説明してください。
解答例
using UnityEngine;

public class PlayerInteraction : MonoBehaviour
{
    // 衝突判定(物理的な衝突時に呼び出される)
    private void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.CompareTag("Enemy"))
        {
            Debug.Log("プレイヤーが敵に衝突");
            // 敵との衝突時の追加処理をここに記述
        }
    }

    // トリガー判定(指定のエリアに入った時に呼び出される)
    private void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.CompareTag("Area"))
        {
            Debug.Log("プレイヤーがエリアに侵入");
            // エリアに入ったときの追加処理をここに記述
        }
    }
}
必要なコンポーネントの設定方法
  • プレイヤーオブジェクト:
    • Rigidbodyコンポーネントを追加する(物理演算が必要なため)。
    • Colliderコンポーネント(例:BoxColliderやCapsuleCollider)を追加する。
  • 敵オブジェクト:
    • Colliderコンポーネントを追加する。
    • タグを「Enemy」に設定する。
  • エリアオブジェクト:
    • Colliderコンポーネントを追加し、「Is Trigger」にチェックを入れる。
    • タグを「Area」に設定する。

演習問題2

問題

OnTriggerEnterを利用して、プレイヤーがアイテムエリアに入ったときにアイテムを取得し、画面上に「アイテムゲット!」と表示するスクリプトを作成してください。さらに、取得したアイテムを非表示にする処理も追加してください。

解答例
using UnityEngine;

public class ItemPickup : MonoBehaviour
{
    // トリガー判定でアイテムを取得する
    private void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.CompareTag("Player"))
        {
            Debug.Log("アイテムゲット!");
            // アイテムを非表示にする処理
            gameObject.SetActive(false);
        }
    }
}
設定のポイント
  • アイテムオブジェクトのColliderに「Is Trigger」をチェックする。
  • プレイヤーオブジェクトにはColliderとRigidbodyを設定する。
  • プレイヤーオブジェクトのタグを「Player」に設定する。

おわりに

Unityの物理演算と衝突判定の基本を理解することは、ゲーム開発における基礎中の基礎です。

今回紹介したOnCollisionEnterとOnTriggerEnterの違いや実際の使い方をマスターすることで、より複雑なシステムへの応用が可能になります。まずは実際にコードを書いて試してみることが、理解を深める一番の近道です。

今回の演習問題を参考に、自分なりのシーンを作成して、さまざまなイベント処理を試してみてください。

この初心者向け記事が、Unityでの開発の第一歩としてお役に立てれば幸いです。