MRが楽しい

MRやVRについて学習したことを書き残す

UnityEventの永続的リスナーと非永続的リスナーの違い

本日は Unity の小ネタ枠です。
UnityEventの永続リスナーと非永続リスナーの違いについて理解できていなかったので記事にします。
f:id:bluebirdofoz:20210720223636j:plain

UnityEvent

Scene に保存可能なコールバック関数を登録します。
docs.unity3d.com

UnityEvent へのコールバック関数の登録は Inspector ビューから行う方法と AddListener を用いる方法があります。
f:id:bluebirdofoz:20210720223655j:plain

docs.unity3d.com

UnityEvent m_MyEvent = new UnityEvent();
void Start()
{
    // イベントへのリスナー登録
    m_MyEvent.AddListener(MyAction);
}

永続的リスナーと非永続的リスナー

UnityEvent に登録されるリスナーには永続的リスナーと非永続的リスナーの2種類のリスナーが存在します。
Inspector ビューは永続的リスナーを、AddListener は非永続的リスナーを登録します。

サンプルスクリプト

動作を実際に確認するため、以下のサンプルスクリプトを作成しました。
・CheckUnityEvent.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class CheckUnityEvent : MonoBehaviour
{
    /// <summary>
    /// テスト用UnityEvent
    /// </summary>
    public UnityEvent TestEvent;

    /// <summary>
    /// UnityEventの実行
    /// </summary>
    public void InvokeEvent()
    {
        // 登録リスナーを呼び出す
        TestEvent.Invoke();
    }

    /// <summary>
    /// 登録リスナー数の確認
    /// </summary>
    public void CheckAddListenerCount()
    {
        Debug.Log("Listener Count : " + TestEvent.GetPersistentEventCount().ToString());
    }

    /// <summary>
    /// スクリプトからのリスナー登録
    /// </summary>
    public void TestAddListener()
    {
        Debug.Log("TestAddListener Called !!!");
        TestEvent.AddListener(TestCallMethod);
    }

    /// <summary>
    /// 試験用呼び出しメソッド
    /// </summary>
    public void TestCallMethod()
    {
        Debug.Log("TestCallMethod Called !!!");
    }
}

永続的リスナー

Inspector ビューから登録したリスナーは永続的リスナーになります。
登録済みの永続的リスナーは Inspector 上から確認できます。
f:id:bluebirdofoz:20210720223724j:plain

永続的リスナーはその登録数を GetPersistentEventCount 関数で取得できます。
f:id:bluebirdofoz:20210720223735j:plain

Invoke で関数呼び出しを実行します。
f:id:bluebirdofoz:20210720223745j:plain

非永続的リスナー

スクリプトから AddListener 関数で登録したリスナーは非永続的リスナーになります。
非永続的リスナーは Inspector 上から確認できません。
f:id:bluebirdofoz:20210720223756j:plain

また、その登録数を GetPersistentEventCount 関数で取得できません。
f:id:bluebirdofoz:20210720223813j:plain

永続的リスナーと同じく Invoke で関数呼び出しを実行します。
f:id:bluebirdofoz:20210720223824j:plain

なお、永続的リスナーと非永続的リスナーは同時に登録可能です。
以下は Inspector からの登録と AddListener の登録を行った場合です。
それぞれの登録関数が実行され、2回メッセージが表示されています。
f:id:bluebirdofoz:20210720223834j:plain