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

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

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

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

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

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

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


ボタンイベントの登録は、下のように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