UnityEvent について。具体的なサンプルの方が分かりやすいと思うので、MRTK のソースコードを例示しながら検証をしてみたいと思います。
イベント (Event) とは
クラスやオブジェクトは、何か重要なことが起こった場合にイベントを使用して他のオブジェクト、またはクラスに通知を送ることができます。イベントを送信するクラスを Publisher (発行者)、イベントを受信するクラスを Subscriber (購読者) と呼びます。
イベント (C# プログラミングガイド) より引用
その他、「観測対象 (Subject) 」/「観測者 (Observer) 」などと呼ばれたりします。イベントに関する用語も UnityEvent と C# event で呼び方が異なる部分があります。
UnityEvent とは
UnityEvent は、追加のプログラミングやスクリプトの設定を行う必要なく、編集時からランタイムへ 永続的 なコールバックを提供する方法です。Unity Editor (GUI) を使って、イベント発生時の処理 (リスナー) を追加することができます。また、スクリプトから動的に非永続なコールバックを追加することも可能です。
リスナー (Listener) は、データの保持の方法によって、以下2種類に分類されます。
- 永続リスナー ( Inspector 上から追加可能で、Scene データとして保存される )
- 非永続リスナー ( スクリプトから動的に追加することができるリスナー、Scene データとして保存されない )
イベントの定義方法
個人的に身近な例だと、UnityEvent は MRTK v2 の Interactable.cs
内で使用されています。
public UnityEvent OnClick = new UnityEvent();
リスナーの追加
永続リスナー
Inspector ウィンドウ で イベントが定義されているコンポーネント に移動して、リスナーを登録します。
非永続リスナー
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.Toolkit.UI;
public class UnityEventSample : MonoBehaviour
{
private Interactable interactable = null;
void Start()
{
// Interactable コンポーネントの取得
interactable = GetComponent<Interactable>();
// イベントリスナーの追加
interactable.OnClick.AddListener(Listener);
}
void Disable()
{
// イベントリスナーを取り除く
interactable.OnClick.RemoveListener(Listener);
}
// イベントリスナーとして登録する関数
void Listener()
{
Debug.Log("Click");
}
}
実際に MRTK v2 の空のシーンに PressableButtonHoloLens2_64×64
を追加して、上記のスクリプト UnityEventSample.cs
をアタッチして、ゲームを再生すると、リスナーが追加されていることが確認できます。
イベントの実行
イベントに追加したリスナーを実行するには UnityEvnet.Invoke()
メソッドを使用します。このメソッドを実行することで、登録されているリスナーが実行されます。MRTK v2 の Interactable.cs
では、PressableButtonHoloLens2
のイベントを PhysicalPressEventRouter
を介して Interactable
へ送信しています。
コンポーネント ( PressableButtonHoloLens2 : PressableButton ) IMixedRealityTouchHandler.OnTouchStarted() → IsTouching() → TouchBegin()
↓
コンポーネント (PhysicalPressEventRouter)
OnHandPressTouched()
↓
コンポーネント (Interactable)
TriggerOnClick() → SendOnClick()
protected void SendOnClick(IMixedRealityPointer pointer)
{
OnClick.Invoke();
}
OnClick.Invoke()
が実行されると、リスナーとして登録された関数が実行されます。
Refs
https://learn.microsoft.com/ja-jp/dotnet/csharp/programming-guide/events/
https://learn.microsoft.com/ja-jp/dotnet/standard/events/