Unityでボタンイベントの登録

Unityでボタンイベントの登録

Unityでスクリプトからボタンイベントを登録する方法とその利点。

関連ページ
Unityの参考書では、よくUI ButtonのInspector上からクリックした時の処理を紐づける方法が紹介してある。
ただこのやり方は、どのButtonからどの関数が呼ばれてるのかコードを見ただけでは追えなくなるのでお勧めできない。

Unityでは、スクリプト上からも簡単にボタンイベントを登録できる。

AddListenerを使ってボタンイベントを登録

例えばボタンをクリックするたびに、「YAY! (クリック回数)」と表示する簡単な処理を作ってみる。


Unity初学者向けの参考書では、下のようにButtonのInspectorから直接関数を紐づける方法が紹介されている。
ButtonのInspectorから直接関数を登録
この方法は一見簡単に見えて、プロジェクトが複雑化するにつれてどこからどの関数が呼ばれてるのか把握が困難になる。

スクリプトからボタンイベントを登録する際のコード全文は下の通り。
using UnityEngine;
using UnityEngine.UI;

public class ButtonTest : MonoBehaviour
{
    [SerializeField] private Text yayText;
    [SerializeField] private Button yayButon;

    private int yayCount;

    private void Start()
    {
        yayButon.onClick.AddListener(OnTapYayButton);
    }

    private void OnTapYayButton()
    {
        yayCount++;
        yayText.text = "YAY " + yayCount;
    }
}

ボタンをアタッチ

まずUI ButtonコンポーネントをInpector上で外部からアタッチする。
    [SerializeField] private Button yayButon;
UI Buttonをアタッチ

[SerializeField] privateではなく、単純にアクセス修飾子をpublicにする方法もあるがこれもおすすめできない。
pubicだとスクリプト上からも外部からアクセスする可能性が出てしまい、コードの可読性が落ちてしまう。

スクリプトからボタンイベントを登録

下のように.onClick.AddListenerを使うとスクリプトからボタンイベントを登録できる。
        yayButon.onClick.AddListener(OnTapYayButton);
ButonのInspectorから直接イベントを登録する場合は、OnTapYayButton関数をpublicにする必要があるか、この方法だとprivateで大丈夫。

もしOnTapYayButtonが引数ありの関数である場合、AddListener内をラムダ式にする必要がある。
    private void Start()
    {
        yayButon.onClick.AddListener(() => OnTapYayButton("テスト"));
    }

    private void OnTapYayButton(string test)
    {
        yayCount++;
        yayText.text = "YAY " + yayCount;
    }

AddListenerの注意点

スクリプトから登録する方法の注意点としては、AddListenerが複数回呼ばれると、イベントもその分だけ複数回呼ばれてしまうこと。
たとえばAddListerをStart()ではなくOnEnable()内で登録したとする。
この場合GameObjectがアクティブ化するたびにAddListenerが呼ばれるので、どんどんイベントが積み重なっていく。
    private void OnEnable()
    {
        yayButon.onClick.AddListener(OnTapYayButton);
    }

見ての通り一回ボタンをタップしただけなのに、OnTapYayButton関数が複数回呼ばれているのが分かる。

もしAddListenerが複数回呼ばれてしまう可能性があるコードである場合、RemoveAllListenersを事前に呼べば重複登録を避けられる。
        yayButon.onClick.RemoveAllListeners();
        yayButon.onClick.AddListener(OnTapYayButton);
0
0