Tsuの雑記¯\_(ツ)_/¯

主に製作メモ・備忘録として使用。製作したアプリのリンクもあります。

【Unity】Button 型を引数にする【C#】

UI.Button を操作するメソッドは,Button型を引数にしましょう。

こうすることで,コードを簡素化しつつバグを防ぎやすくなります。

もちろん UI.Button に限らず,他の UI にも有効な方法です。

それでは,いくつか実例を挙げて御説明いたします。

(Unity 2018.3.0f2)

"Swan"と書かれたボタンを押すとwhite,"Crow"と書かれたボタンを押せばblackと返すプログラムを作ります。

ボタンの数だけメソッドを用意する場合

public class NewBehaviourScript : MonoBehaviour
{
    public void SwanButton()
    {
        Debug.Log("white");
    }

    public void CrowButton()
    {
        Debug.Log("black");
    }
}

上記のようなスクリプトファイルを,適当な GameObject にアタッチします。

UnityEditor の Inspector ウィンドウで スクリプトをアタッチしている画像
GameObject に NewBehaviourScript.cs をアタッチ

先程スクリプトをアタッチした GameObject を,UI.Button の OnClick() イベントで選択します。

次に "No Function" と表示されているボタンをクリックして,クラス名→メソッド名の順に探して決定します。

UnityEditor の Inspector ウィンドウで OnClick() イベントネントを操作している画像
UI.Button の OnClick() イベント

長所

・引数等の設定が不要なため,ミスが起きにくい。

短所

・ボタンの数だけメソッドが増えるため,コードの可読性が下がる。

1つのメソッドを string 型や int 型で分岐させる場合

public class NewBehaviourScript : MonoBehaviour
{
    public void Button(string button)
    {// 引数を string 型に設定
        if (button == "swan")
        {
            Debug.Log("white");
        }
        else
        {
            Debug.Log("black");
        }
    }
}

今度は OnClick() イベントの見た目が,少し変わります。

UI.Button の OnClick() イベントでメソッド名を選択するとテキストボックスが現れるので,ボタン識別のための文字列を入力しましょう。

OnClick() イベントに"swam"と入力している画像
文字列に注目

実はここまでにミスがあり,バグが発生しています。

UnityEditor の Console ウィンドウで両方のボタンに"black"を返している画像
どちらを押しても"black"を返すバグ

原因は,ボタン識別のための文字列が"swam"となっている事です。

このミスはstring型特有というわけでもなく,仮に int 型を引数にしたとしても不一致は起こり得ます。

長所

・1つのメソッドの中で分岐するため,コードを簡素化できる

短所

スクリプトと UnityEditor とで,不一致を起こすおそれがある。

1つのメソッドを Button 型で分岐させる場合

// "UnityEngine.UI.Button"を"Button"と短縮表記できるようになる
using UnityEngine.UI;

public class NewBehaviourScript : MonoBehaviour
{
    // UnityEditor の Inspector 上に表示
    [SerializeField] Button swanButton = null;
    [SerializeField] Button crowButton = null;

    public void Button(Button button)
    {// 引数を Button 型に設定
        if (button == swanButton)
        {
            Debug.Log("white");
        }
        else
        {
            Debug.Log("black");
        }
    }
}

スクリプトをアタッチした GameObject の inspector ウィンドウに UI.Button の変数名が表示されるので,対応する UI.Button を選択します。

UnityEditor の Inspector ウィンドウで Script コンポーネントを操作している画像
GameObject に SwanButton をアタッチ

UI.Button の OnClick() イベントで,このUI.Button そのものを選択しましょう。

OnClick() イベントで SwanButton を選択している画像
UI.Button そのものをアタッチ

これで引数の誤記を防げるうえ,複数の UI.Button の管理を1つのメソッドにまとめることも出来ました。

更にこの UI.Button を複製すると「自分自身を引数とする」状態も保持されるため,細かい事ですが2つ目以降の設定効率も上がります。

複製した UI.Button も自分自身をアタッチした状態になっている画像
複製した UI.Button も自分自身をアタッチした状態になっている

長所

・1つのメソッドの中で分岐するため,コードを簡素化できる

スクリプトと UnityEditor とで,不一致を起こしにくい。

短所

・UI.Button を全て,スクリプト内で宣言する必要がある。

結論

短所はあるものの,3つ目の「Button型を引数にする」方法が最良かと思います。

UI.Button の Text をスクリプト上で変更する方法については,以下の記事を御覧くださいませ。

tsu-games.hatenablog.com