LoginSignup
1
0

[MR Dev Tips #16] UnityEvent について

Last updated at Posted at 2023-09-11

UnityEvent について。具体的なサンプルの方が分かりやすいと思うので、MRTK のソースコードを例示しながら検証をしてみたいと思います。

イベント (Event) とは

クラスやオブジェクトは、何か重要なことが起こった場合にイベントを使用して他のオブジェクト、またはクラスに通知を送ることができます。イベントを送信するクラスを Publisher (発行者)、イベントを受信するクラスを Subscriber (購読者) と呼びます。

イベント (C# プログラミングガイド) より引用

その他、「観測対象 (Subject) 」/「観測者 (Observer) 」などと呼ばれたりします。イベントに関する用語も UnityEvent と C# event で呼び方が異なる部分があります。

UnityEvent とは

UnityEvent は、追加のプログラミングやスクリプトの設定を行う必要なく、編集時からランタイムへ 永続的 なコールバックを提供する方法です。Unity Editor (GUI) を使って、イベント発生時の処理 (リスナー) を追加することができます。また、スクリプトから動的に非永続なコールバックを追加することも可能です。

リスナー (Listener) は、データの保持の方法によって、以下2種類に分類されます。

  • 永続リスナー ( Inspector 上から追加可能で、Scene データとして保存される )
  • 非永続リスナー ( スクリプトから動的に追加することができるリスナー、Scene データとして保存されない )

UnityEvent

イベントの定義方法

個人的に身近な例だと、UnityEvent は MRTK v2 の Interactable.cs 内で使用されています。

Interactable.cs
public UnityEvent OnClick = new UnityEvent();

リスナーの追加

永続リスナー

Inspector ウィンドウ で イベントが定義されているコンポーネント に移動して、リスナーを登録します。

image.png

非永続リスナー

UnityEventSample.cs
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 をアタッチして、ゲームを再生すると、リスナーが追加されていることが確認できます。

image.png

イベントの実行

イベントに追加したリスナーを実行するには UnityEvnet.Invoke() メソッドを使用します。このメソッドを実行することで、登録されているリスナーが実行されます。MRTK v2 の Interactable.cs では、PressableButtonHoloLens2 のイベントを PhysicalPressEventRouter を介して Interactable へ送信しています。

コンポーネント ( PressableButtonHoloLens2 : PressableButton ) IMixedRealityTouchHandler.OnTouchStarted() → IsTouching() → TouchBegin()

コンポーネント (PhysicalPressEventRouter)
OnHandPressTouched()

コンポーネント (Interactable)
TriggerOnClick() → SendOnClick()

Interactable.cs
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/

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0