チュートリアル:Unityでの衝突・トリガーイベント処理と delegate/event の活用

以下は、これまでの内容を踏まえたUnityエンジンを使った実践的なチュートリアルです。このチュートリアルでは、衝突(Collision)やトリガー(Trigger)のイベント処理をdelegateとeventを用いて実装し、実際にUnity上で動作させる方法を学びます。

1. チュートリアルの概要

このチュートリアルでは、Unityにおいて以下を実践的に学びます。

  • Unityプロジェクトの作成と基本シーンの設定
  • C# における delegate の定義と event キーワードの利用方法(両者の同時利用)
  • 衝突(Collision)とトリガー(Trigger)のイベント処理用スクリプトの作成
  • 別スクリプトから両イベントのハンドラを登録し、実際にイベント発生時に処理を実行

1. 必要な準備

1.1 Unity プロジェクトの作成

  1. Unity Hub から「New Project」を選択し、テンプレートは「3D」を選びます。
  2. プロジェクト名を例として CollisionTriggerTutorial とし、作成します。

1.2 シーンの設定

  1. シーンに Plane(床オブジェクト)を配置して、オブジェクトの落下先とします。
  2. 衝突を検知するために Cube を配置します。
    • Cube には Box Collider が付いているので、Rigidbody コンポーネントも追加して物理演算を有効にします。
  3. トリガーを検知するために、別の Cube を配置し、Box Collider の Is Trigger オプションにチェックを入れます。

3. スクリプトの作成

3.1 衝突イベント用スクリプト(CollisionTriggerHandler.cs)

以下のコードは、delegate型とeventを組み合わせた形で衝突イベントを実装した例です。
このスクリプトは、衝突が発生したときに外部から登録されたイベントハンドラを呼び出します。

using System;
using UnityEngine;

// ① delegate 型の定義(Collisionを引数に取る)
public delegate void CollisionDelegate(Collision collision);

public class CollisionTriggerHandler : MonoBehaviour
{
    // ② event として delegate 型を利用して宣言(外部からは「+=」や「-=」のみ可能)
    public event CollisionDelegate OnCollisionEnterEvent;

    // Unityが衝突開始時に自動呼び出すイベント関数
    private void OnCollisionEnter(Collision collision)
    {
        // ③ nullチェック付きでイベントを発火
        OnCollisionEnterEvent?.Invoke(collision);
    }
}

ポイント:

  • delegate 定義:
    CollisionDelegate は、衝突イベントに対するメソッドの型を定義しています。
  • event 宣言:
    OnCollisionEnterEvent は event として宣言され、外部からの直接操作(代入や発火)は制限され、登録(+=)・解除(-=)のみ可能です。

3.2 イベントハンドラ登録用スクリプト(Example.cs)

次に、別のスクリプトから先ほどのイベントにハンドラを登録し、衝突発生時の処理を実装します。

using UnityEngine;

public class Example : MonoBehaviour
{
    // Hierarchy上のオブジェクトにアタッチされている CollisionTriggerHandler を参照
    public CollisionTriggerHandler collisionHandler;

    private void Start()
    {
        // 衝突イベントにハンドラを登録
        collisionHandler.OnCollisionEnterEvent += HandleCollisionEnter;
    }

    // 衝突イベント発生時に呼ばれるハンドラ
    private void HandleCollisionEnter(Collision collision)
    {
        Debug.Log("衝突発生: " + collision.gameObject.name);
    }
}

ポイント:

  • イベントの登録:
    += を使って HandleCollisionEnter メソッドをイベントに追加します。
  • ハンドラの動作:
    衝突が発生すると、登録されたメソッドが呼ばれ、コンソールに衝突対象のオブジェクト名が出力されます。

4. Unityエディタ上での設定

4.1 スクリプトのアタッチ

  1. CollisionTriggerHandler.cs を衝突検知を行いたいオブジェクト(例:Cube)にアタッチします。
    • Cubeには Rigidbody コンポーネントが必要です(物理演算が働くため)。
  2. Example.cs を別のオブジェクト(または同じオブジェクト)にアタッチします。

4.2 インスペクターでの参照設定

  • Example.cs のインスペクター上で、collisionHandler フィールドに対象のオブジェクト(CollisionTriggerHandlerがアタッチされたCube)をドラッグ&ドロップして設定します。

5. チュートリアルの実行

  1. Unityエディタ上部の再生ボタンをクリックして、プレイモードに入ります。
  2. Rigidbody を持つ Cube が床(Plane)に衝突すると、Example.cs のハンドラが呼ばれ、コンソールに「衝突発生: Cube」のようなメッセージが表示されます。

6. トリガーイベントの実装(オプション)

衝突イベントと同様に、トリガーイベントも実装できます。以下は、トリガーイベント用のコード例です。

using System;
using UnityEngine;

public delegate void TriggerDelegate(Collider other);

public class TriggerHandler : MonoBehaviour
{
    public event TriggerDelegate OnTriggerEnterEvent;

    private void OnTriggerEnter(Collider other)
    {
        OnTriggerEnterEvent?.Invoke(other);
    }
}

利用例:
トリガー用オブジェクト(ColliderのIs Triggerにチェック済み)にこのスクリプトをアタッチし、同様に外部からイベントハンドラを登録することで、トリガー領域への進入を検知できます。


7. まとめ

このチュートリアルでは、以下のことを学びました。

  • Unityの衝突(Collision)イベントとトリガー(Trigger)イベントの基本概念
  • C# における delegate の定義と event の利用方法
  • delegate と event を組み合わせることで、外部からの操作を制限しつつ安全にイベント駆動型プログラミングを実現する方法
  • 実際にUnityエディタ上でスクリプトを動作させ、衝突やトリガーのイベントを検知する手順

これらの知識を応用することで、より堅牢で柔軟なゲームロジックやユーザーインタラクションの実装が可能になります。ぜひ、さまざまなシーンで試してみてください。