Unityにおける衝突・トリガーイベント処理と delegate/event の同時利用

本資料では、Unityでの衝突(コリジョン)やトリガーイベントの処理方法を解説し、C# における Actiondelegate、および event の使い方とそれぞれの違い、さらに delegate と event を同時に使う方法について整理します。

delegate はメソッド参照の基本機能であり、event はその delegate をラップして外部からの操作(直接の代入や呼び出し)を制限する仕組みです。delegate と event は密接に関連しており、一般的に event は delegate 型を用いて宣言されます。


1. Action を使った基本のイベント処理

1.1 using ディレクティブとクラス定義

まずは Unity で必要な名前空間をインポートし、MonoBehaviour を継承したクラスを作成します。

using System;
using UnityEngine;

public class CollisionTriggerHandler : MonoBehaviour
{
    // コリジョンイベント(Action を利用)
    public Action<Collision> OnCollisionEnterEvent;

    private void OnCollisionEnter(Collision collision)
    {
        OnCollisionEnterEvent?.Invoke(collision);
    }
}
C#
  • using System;
    C# の基本機能(ここでは Action など)を利用するために必要です。
  • using UnityEngine;
    Unity 固有のクラス(MonoBehaviour、Collision、Collider など)を利用するために必要です。

1.2 Unity のイベント関数との連携

  • OnCollisionEnter:
    Unity が衝突イベント発生時に自動で呼び出す関数です。
  • ?.Invoke(collision):
    Action に登録されたメソッドが存在する場合にのみ呼び出し、null の場合は安全にスキップします。

2. event キーワードを活用した安全なイベント実装

2.1 event キーワードの特徴

event は内部で delegate を利用していますが、delegate フィールドと異なり以下の特徴があります:

  • カプセル化:
    外部から直接イベントの中身を上書きできず、「+=」や「-=」による登録・解除のみが可能です。
  • 発火の制限:
    イベントの発火(Invoke)はクラス内部に限定され、外部から直接呼び出すことはできません。

2.2 event を使った実装例

using System;
using UnityEngine;

public class CollisionTriggerHandler : MonoBehaviour
{
    // コリジョンイベントを event として宣言(外部は登録・解除のみ可能)
    public event Action<Collision> OnCollisionEnterEvent;

    private void OnCollisionEnter(Collision collision)
    {
        OnCollisionEnterEvent?.Invoke(collision);
    }
}
C#
  • 外部からの利用例:
public class Example : MonoBehaviour
{
    public CollisionTriggerHandler collisionHandler;

    private void Start()
    {
        // 「+=」を使ってイベントにハンドラを登録
        collisionHandler.OnCollisionEnterEvent += HandleCollisionEnter;
    }

    private void HandleCollisionEnter(Collision collision)
    {
        Debug.Log("衝突開始: " + collision.gameObject.name);
    }
}
C#

この実装により、外部からはハンドラの追加(+=)や削除(-=)のみが可能となり、直接代入や発火することが防がれます。


3. delegate の基本と event との同時利用

3.1 delegate の基本概念

  • delegate:
    メソッドへの参照を保持する基本機能です。引数や戻り値の型を定義し、任意のメソッドを呼び出す手段として使用されます。
    delegate 型のフィールドは外部から直接代入できるため、誤って上書きされるリスクがあります。

3.2 delegate と event を組み合わせた実装例

delegate 型を定義し、その型を用いて event を宣言することで、外部からの登録操作(+=, -=)のみを許可しながら、内部で安全にイベントを発火できます。

using System;
using UnityEngine;

// delegate 型の定義(引数として Collision を受け取る)
public delegate void CollisionDelegate(Collision collision);

public class CollisionTriggerHandler : MonoBehaviour
{
    // event として delegate 型を利用して宣言
    public event CollisionDelegate OnCollisionEnterEvent;

    private void OnCollisionEnter(Collision collision)
    {
        OnCollisionEnterEvent?.Invoke(collision);
    }
}
C#

この例では、

  • CollisionDelegate:
    衝突イベントに対応するメソッドの型を定義しています。
  • public event CollisionDelegate OnCollisionEnterEvent;
    ここで、定義した delegate 型を使って event を宣言しています。これにより、外部からは「+=」や「-=」による操作のみが許可され、直接の代入や発火はできません。

4. まとめ

  • Action を使った実装:
    簡潔な記法でイベント処理を実現でき、初学者にも理解しやすい実装方法です。
  • event の利用:
    event は内部で delegate を利用し、外部からの直接操作(上書きや直接発火)を制限することで安全性とカプセル化を提供します。
  • delegate と event の同時利用:
    delegate はメソッド参照の基本機能であり、event はその delegate をラップすることで外部からの操作を制限します。
    delegate 型を定義し、その型を使って event を宣言することで、柔軟かつ安全なイベント駆動プログラミングが可能となります。

これらの概念と実装方法を理解することで、Unity における衝突・トリガーイベント処理を効果的に設計でき、堅牢なコードを書くことが可能になります。

Unity,イベント

Posted by hidepon