UnityEvent<int>とは何か

UnityEvent<int>は、Unityのイベントシステムで使用されるジェネリック型のイベントクラスです。UnityEventは引数のないイベントを表しますが、UnityEvent<T0>1つの引数を持つイベントを表します。ここで、T0は引数の型を示します。

つまり、UnityEvent<int>整数型の引数を持つイベントを作成するためのクラスです。このイベントは、他のスクリプトやインスペクターからアクセスでき、整数のデータ(例えばダメージ量など)をリスナーに渡すことができます。


UnityEvent<int>の使い方

1. イベントの宣言

public UnityEvent<int> onDamaged;
  • onDamagedという名前のイベントを宣言します。
  • このイベントは、int型の引数を1つ取ります。

2. イベントの発行(Invoke)

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        int damageAmount = 10;
        onDamaged.Invoke(damageAmount); // イベントを発行し、ダメージ量を渡す
    }
}
  • Invokeメソッドを使用して、イベントを発行します。
  • 引数としてdamageAmountを渡し、登録されたリスナー(メソッド)に通知します。

3. イベントハンドラの登録

他のスクリプトで、このイベントに対してリスナーを登録します。

public class GameManager : MonoBehaviour
{
    public EventTrigger eventTrigger;

    void Start()
    {
        eventTrigger.onDamaged.AddListener(ApplyDamage);
    }

    void ApplyDamage(int damage)
    {
        Debug.Log($"プレイヤーが{damage}のダメージを受けた!");
    }
}
  • AddListenerメソッドを使用して、ApplyDamageメソッドをイベントに登録します。
  • ApplyDamageメソッドは、int型の引数を1つ取る必要があります。

メリット

コードがシンプルになる

  • カスタムのイベントクラス(例えばDamageEvent)を定義せずに済むため、コードが簡潔になります。
  • 直接UnityEvent<int>を使用することで、余分なクラス定義を省略できます。

インスペクターでの設定が容易

  • UnityEvent<int>はシリアライズ可能なので、インスペクター上でイベントリスナーを設定できます。
  • コードを変更せずに、インスペクターからイベントの追加や削除が可能です。

注意点

Unityのバージョンによる違い

  • Unity 2019.3以降
    • ジェネリックなUnityEvent<T>のシリアライズがサポートされており、インスペクター上で編集可能です。
    • そのため、public UnityEvent<int> onDamaged;と直接宣言して問題ありません。
  • Unity 2019.3未満
    • ジェネリック型のシリアライズがサポートされていないため、インスペクター上で表示されません。
    • この場合、カスタムクラスを定義し、[System.Serializable]属性を付与する必要があります。
  using UnityEngine;
  using UnityEngine.Events;

  // カスタムイベントクラスの定義
  [System.Serializable]
  public class DamageEvent : UnityEvent<int> { }

  public class EventTrigger : MonoBehaviour
  {
      public DamageEvent onDamaged;

      // 残りのコードは同じ
  }

実際のコード例(Unity 2019.3以降)

EventTrigger.cs

using UnityEngine;
using UnityEngine.Events;

public class EventTrigger : MonoBehaviour
{
    public UnityEvent<int> onDamaged;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            int damageAmount = 10;
            onDamaged.Invoke(damageAmount); // ダメージ量を渡してイベントを発行
        }
    }
}

GameManager.cs

using UnityEngine;

public class GameManager : MonoBehaviour
{
    public EventTrigger eventTrigger;

    void Start()
    {
        // イベントハンドラを登録
        eventTrigger.onDamaged.AddListener(ApplyDamage);
    }

    void ApplyDamage(int damage)
    {
        Debug.Log($"プレイヤーが{damage}のダメージを受けた!");
    }
}

インスペクターでの設定方法

  • EventTriggerの設定
    • EventTriggerスクリプトをアタッチしたゲームオブジェクトを選択します。
    • インスペクター上でOn Damagedイベントが表示されます。
    • +ボタンをクリックしてリスナーを追加します。
    • 対象のゲームオブジェクト(例:GameManagerがアタッチされたオブジェクト)をドラッグ&ドロップします。
    • 関数リストから、GameManagerApplyDamage(int)メソッドを選択します。
  • 引数の設定
    • コード内で引数を渡しているため、インスペクター上で引数を指定する必要はありません。

複数の引数を持つイベント

UnityEventは最大4つの引数を持つことができます。例えば、文字列と整数の2つの引数を持つイベントを宣言するには:

public UnityEvent<string, int> onEventWithTwoArgs;

イベントを発行する際:

onEventWithTwoArgs.Invoke("メッセージ", 42);

リスナーとなるメソッドは、対応する引数を持つ必要があります。

void OnEventReceived(string message, int number)
{
    Debug.Log($"受け取ったメッセージ:{message}, 数値:{number}");
}

イベントハンドラの削除

登録したリスナーを削除する場合は、RemoveListenerメソッドを使用します。

eventTrigger.onDamaged.RemoveListener(ApplyDamage);

特定の条件下でリスナーを解除したい場合に使用します。


まとめ

  • public UnityEvent<int> onDamaged;は、整数型の引数を持つイベントを宣言するための方法です。
  • このイベントを使用すると、他のスクリプトからリスナーを登録して、イベントが発生したときに引数とともに処理を実行できます。
  • Unityのバージョンが2019.3以降であれば、ジェネリックなUnityEvent<T>を直接使用して、インスペクター上で編集可能です。
  • イベントシステムを活用することで、コードの再利用性や保守性が向上します。

補足情報

イベントの利点

  • 疎結合な設計:イベントを使用することで、オブジェクト間の依存関係を減らし、柔軟な設計が可能になります。
  • 再利用性の向上:同じイベントに複数のリスナーを登録できるため、機能の追加や変更が容易です。
  • 拡張性:新しい機能を追加する際に、既存のコードを変更せずにイベントリスナーを追加できます。

注意事項

  • パフォーマンス:大量のイベントやリスナーを使用すると、パフォーマンスに影響を与える可能性があります。必要に応じて最適化を検討してください。
  • メモリリーク:リスナーの登録と解除を適切に行わないと、不要な参照が残り、メモリリークの原因になることがあります。

結論

public UnityEvent<int>は、引数を持つイベントを簡潔に宣言し、柔軟なイベント駆動型のプログラミングを実現するための強力なツールです。Unityのイベントシステムを効果的に活用することで、コードの品質と開発効率を高めることができます。ぜひプロジェクトで活用してみてください。

Unity,イベント

Posted by hidepon