「ボタンが押されたらイベントが発生」をスクリプトで実現

2024年4月4日

このコードは、Unityエンジンで動作するゲームオブジェクトにアタッチされたStartButtonクラスを定義しています。このクラスは、Buttonコンポーネントを必要とし、ボタンがクリックされたときにMainSceneをロードするリスナーを登録します。

ボタンイベントの登録

ラムダ式でメソッド(イベントハンドラ)を登録

Unityの場合、インスペクターのところでビジュアル登録もできますが、コードでの登録もできます

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[RequireComponent(typeof(Button))]
public class StartButton : MonoBehaviour
{
    void Start()
    {
        var button = GetComponent<Button>();

        button.onClick.AddListener(() => SceneManager.LoadScene("MainScene"));
    }
}

具体的には、以下のような処理が行われています。

  1. using文により、Unityエンジンで使用するクラスをインポートしています。
  2. [RequireComponent(typeof(Button))]属性により、このクラスがアタッチされたゲームオブジェクトにButtonコンポーネントがアタッチされていることを要求しています。
  3. Startメソッドが定義されており、アタッチされたゲームオブジェクトのButtonコンポーネントを取得しています。
  4. 取得したButtonコンポーネントのonClickイベントにLoadMainSceneメソッドを登録しています。onClickイベントは、Buttonがクリックされたときに呼び出されるイベントであり、LoadMainSceneメソッドはMainSceneをロードするための処理を行います。
  5. LoadMainSceneメソッドが定義されており、SceneManager.LoadSceneメソッドを使用してMainSceneをロードしています。

このように、StartButtonクラスは、ボタンがクリックされたときにMainSceneをロードするためのリスナーを登録するためのスクリプトとして機能します。このスクリプトがアタッチされたゲームオブジェクトにButtonコンポーネントがアタッチされていない場合、エラーが発生します。

AddListenerメソッドのUnityEnjineの内部実装部分

[Serializable]
public class UnityEvent : UnityEventBase
{
    public void AddListener (UnityAction call)
    {
        AddCall (GetDelegate (call));
    }
}

デリゲートとは

public delegate void UnityAction ();

このコードは、C#言語においてUnityエンジンで使用されるイベントシステムで利用されるデリゲート型であるUnityActionを定義しています。

デリゲートは、メソッドを参照する型であり、イベントを処理するために使用されます。UnityActionは、戻り値がvoidで、引数を持たないメソッドを参照するためのデリゲート型です。これは、Unityエンジンで使用されるイベントリスナーのシグネチャー(メソッドの形式)と一致します。

イベントリスナーは、イベントが発生したときに呼び出されるメソッドです。これらのメソッドは、通常はイベントの種類に応じたUnityActionデリゲート型の引数を取ります。

例えば、以下のようなイベントがあるとします。

public event UnityAction OnButtonClicked;

このイベントが発生したときには、OnButtonClickedに登録されたUnityAction型のメソッドが呼び出されます。イベントを購読するオブジェクトは、OnButtonClickedイベントに自身のメソッドを登録することで、イベントが発生した際にそのメソッドを実行することができます。

ラムダ式を使わないパターン

AddListenerメソッドの引数は、メソッド本体の参照なので、ここに実際のメソッド名を代入するのと同じことになります
条件としては、戻り値なしで引数なしになります

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[RequireComponent(typeof(Button))]
public class StartButton : MonoBehaviour
{
    void Start()
    {
        var button = GetComponent<Button>();

        button.onClick.AddListener(LoadMainScene);
    }

    void LoadMainScene()
    {
        SceneManager.LoadScene("MainScene");
    }
}