UnityEvent を使ったイベント登録入門チュートリアル – EventDispatcher と EventReceiver の連携(int 型引数付き/コード登録版)

2026年10月1日

広告

この資料では、初めは単なるメソッド定義から始め、シーン開始時に呼び出す方法、そして最終的に UnityEvent を利用して、異なる GameObject にアタッチされたスクリプト間で int 型の引数付きイベントをコード内で登録・発行する手順を解説します。
使用するスクリプトと GameObject は以下の通りです。

  • EventDispatcher.cs
    (イベント発行側のスクリプト。コード内でリスナーを登録)
    → アタッチする GameObject の名称:EventSender
  • EventReceiver.cs
    (イベント受信側のスクリプト。発行されたイベントを受け取る)
    → アタッチする GameObject の名称:EventListener

1. 初めに:単なるメソッドの定義(引数なし)

まずは、DisplayGreeting() というメソッドを定義しただけの状態です。この段階ではメソッドは存在するものの、どこからも呼び出されないため実行(発行)されません。

using UnityEngine;

public class EventDispatcher : MonoBehaviour
{
    // 「こんにちは、世界!」を表示するメソッド(定義のみ)
    void DisplayGreeting()
    {
        Debug.Log("こんにちは、世界!");
    }
}

ポイント
この状態では、単にメソッドが存在するだけで、実行(発行)されることはありません。


2. Start() からのメソッド呼び出し(引数なし)

次に、Start() メソッド内で DisplayGreeting() を呼び出すようにコードを変更します。これにより、シーン開始時にメソッドが自動的に実行され、コンソールに「こんにちは、世界!」が出力されます。

using UnityEngine;

public class EventDispatcher : MonoBehaviour
{
    void Start()
    {
        // シーン開始時に DisplayGreeting() を呼び出す
        DisplayGreeting();
    }

    void DisplayGreeting()
    {
        Debug.Log("こんにちは、世界!");
    }
}

ポイント

  • Start() は MonoBehaviour の初期化メソッドです。
  • シーン開始と同時に DisplayGreeting() が実行され、コンソールにメッセージが表示されます。

3. int 型引数を渡すためのコード更新(コードでのリスナー登録)

ここから、int 型の引数を渡すために、イベントの型を UnityEvent<int> に変更し、さらにリスナーの登録をインスペクターではなくコード内で行います。
また、Start() 内でイベント発行時に数値(例として 100)を渡します。

using UnityEngine;
using UnityEngine.Events;

public class EventDispatcher : MonoBehaviour
{
    // UnityEvent<int> 型のイベント(int 型引数付き)
    public UnityEvent<int> greetingEvent;

    void Awake()
    {
        // イベントが未初期化の場合は初期化する
        if (greetingEvent == null)
            greetingEvent = new UnityEvent<int>();
    }

    void Start()
    {
        // コードでリスナーを登録
        // 1. 自分自身のメソッドをリスナーとして登録
        greetingEvent.AddListener(DisplayGreetingWithInt);

        // 2. "EventListener" という名前の GameObject から EventReceiver コンポーネントを取得してリスナーとして登録
        EventReceiver receiver = GameObject.Find("EventListener")?.GetComponent<EventReceiver>();
        if (receiver != null)
        {
            greetingEvent.AddListener(receiver.DisplayGreetingWithInt);
        }
        else
        {
            Debug.LogWarning("EventListener が見つからないか、EventReceiver コンポーネントがアタッチされていません。");
        }

        // シーン開始時に、登録された全てのメソッドへ int 型引数 100 を渡してイベントを発行する
        greetingEvent.Invoke(100);
    }

    // int 型引数付きのメソッド
    public void DisplayGreetingWithInt(int value)
    {
        Debug.Log("EventSender より: " + value + " のメッセージ こんにちは、世界!");
    }
}

ポイント

  • イベントの型を UnityEvent<int> に変更することで、int 型の引数を渡せるようになります。
  • greetingEvent.AddListener(…) を使い、インスペクターを介さずにリスナーをコードで登録します。
  • GameObject.Find を用いて、別の GameObject(EventListener)から EventReceiver コンポーネントを取得し、リスナーに追加しています。

4. 別の GameObject のスクリプトのメソッドも実行する(int 型引数付き/コード登録版)

次に、別の GameObject にアタッチされた EventReceiver.cs を、int 型の引数を受け取るように作成します。
こちらはコード内でイベントリスナーとして登録されるため、インスペクターでの設定は不要です。

EventReceiver.cs の作成

using UnityEngine;

public class EventReceiver : MonoBehaviour
{
    // int 型引数を受け取るメソッド
    public void DisplayGreetingWithInt(int value)
    {
        Debug.Log("EventListener よりご挨拶: " + value + " のメッセージ こんにちは、世界!");
    }
}

ポイント

  • このスクリプトは、EventListener という名前の GameObject にアタッチしてください。
  • コード内で EventDispatcher がリスナーとして登録するため、インスペクターでの設定は不要です。

実行結果


5. まとめ

  1. 単なるメソッド定義(引数なし)
    • まずは DisplayGreeting() というメソッドを定義するだけの状態。
  2. Start() から呼び出す(引数なし)
    • シーン開始時に直接 DisplayGreeting() を実行してメッセージを出力する方法を学習。
  3. int 型引数を渡すためのコード更新(コード登録版)
    • イベントの型を UnityEvent<int> に変更し、コード内で AddListener() を使って自分自身および別の GameObject のメソッドを登録。
    • Invoke(100) により、数値 100 を引数として渡す方法を習得。
  4. 他の GameObject のスクリプトのメソッドも実行(int 型引数付き/コード登録版)
    • EventSender と EventListener の双方で、int 型引数付きのメソッド(DisplayGreetingWithInt)をコード内で登録し、シーン再生時に連携して処理を実行する仕組みが実現できます。

この手順を通して、UnityEvent の基本的な使い方に加え、コード内でのイベントリスナー登録と、引数付きのイベント発行・受信の方法を理解し、実際のプロジェクトに柔軟に応用できるようになります。

ここからは、受信側が自分のメソッドを登録する構成に切り替えます。前半の発行側コードも、下記のEventDispatcherへ置き換えてください。発行側と受信側の両方から同じメソッドを登録する必要はありません。

両方の Start() で登録と発火を行うと、実行順によって登録前に発火してしまう可能性があります。この例では受信側の OnEnable() で登録し、発行側の Start() で発火します。

対象は、シーンにあらかじめ配置し、再生開始時に両方のGameObjectとコンポーネントが有効な場合です。無効な受信側を後から有効にしても、過去のイベントは再送されません。イベントはフィールド宣言で初期化し、発行側のAwakeだけに初期化を任せない構成にします。

EventDispatcher.cs(発行側)

using UnityEngine;
using UnityEngine.Events;

public class EventDispatcher : MonoBehaviour
{
    public UnityEvent<int> greetingEvent = new UnityEvent<int>();

    private void Start()
    {
        greetingEvent.Invoke(100);
    }
}

EventReceiver.cs(受信側)

using UnityEngine;

public class EventReceiver : MonoBehaviour
{
    [SerializeField] private EventDispatcher dispatcher;
    private EventDispatcher subscribedDispatcher;

    private void OnEnable()
    {
        if (dispatcher == null)
        {
            Debug.LogWarning("DispatcherをInspectorで設定してください。", this);
            return;
        }
        subscribedDispatcher = dispatcher;
        subscribedDispatcher.greetingEvent.AddListener(DisplayGreetingWithInt);
    }

    private void OnDisable()
    {
        if (subscribedDispatcher != null)
        {
            subscribedDispatcher.greetingEvent.RemoveListener(DisplayGreetingWithInt);
        }
        subscribedDispatcher = null;
    }

    public void DisplayGreetingWithInt(int value)
    {
        Debug.Log($"EventListenerが受け取った値: {value}", this);
    }
}

Inspectorの設定と実行

1. EventSenderにEventDispatcherを、EventListenerにEventReceiverを付けます。
2. EventListenerのInspectorにあるDispatcher欄へEventSenderをドラッグします。
3. EventSenderのGreeting Eventに以前のInspector登録が残っていたら削除します。
4. 両方のGameObjectとコンポーネントを有効にして再生します。
5. Consoleに「EventListenerが受け取った値: 100」が1回表示されることを確認します。

この例でも、発行側への参照はInspectorで設定します。「イベントのメソッドをコードで登録すること」と「オブジェクトへの参照をInspectorで設定すること」は別の操作です。

OnEnable() と OnDisable() を対にすると、受信コンポーネントが有効な間だけイベントを購読できます。解除時には、実際に登録した発行側を使います。再有効化しても、起動時に発火した100を再送する仕組みではありません。

訪問数 179 回, 今日の訪問数 1回

広告

Unity,イベント

Posted by hidepon