Unityでボタンにイベントを付ける方法はいくつかありますが、KuroMikanはC#スクリプトからButtonにAddListenerする方法をよく使います。
ゲームの規模が小さい時は、ボタン毎にスクリプトを作ってアタッチしていました。最初はコードすっきり最高〜とか思っていたのですが、開発規模が大きくなるにつれてボタン用のスクリプト(しかも数行しかない)が大量に増殖してしまった結果、スクリプトからButtonにAddListenerする方法に落ち着きました。
今回は一般的なAddListenerの方法と、引数付きAddListenerの方法、for文を使うときの注意点を紹介しようと思います。
ButtonにAddListenerする方法
最もシンプルなAddlistener
「ボタン名.onClick.AddListener(関数名)」とすることで、ボタンを押したときに指定した関数を実行させることができます。
一般的なAddListenerのコードとしては下記の通りになると思います。
void Start()
{
button.onClick.AddListener(buttonClick); //クリック時にbuttonClick()を発火させる
}
void buttonClick()
{
Debug.Log("クリックしたで");
}
極めて簡単にクリック動作を指定することができます。インスペクターからあれこれする必要もありません。
引数付きAddListener(失敗例)
次に引数が必要な関数を登録する方法です。
void buttonClick(int num) { }
このような関数があったとして、num にクリックしたボタンの番号を入れるケースを想定してみます。
ボタンの数だけfor文をぶん回すわけですが、まずは失敗例から見ていきましょう。
void Start()
{
for (var num = 0; num < 10; num ++)
{
buttons[num].onClick.AddListener(() => buttonClick(num));
}
}
void buttonClick(int num)
{
Debug.Log($"{num}をクリックしたで");
}
省略していますが、配列buttons[]にはButtonがたくさん入っています。
for文で10回ほどぶん回して、その値を引数としてbuttonClickに渡します。
KuroMikanが真っ先に思いついたコードなんですが、一見これでいいと思うじゃないですか?
いざ実行してみると、どのボタンをクリックしても「9をクリックしたで」と表示されてしまいます。
違う、そうじゃない……。
引数付きAddListener(成功例)
正しいコードはこちらです。
void Start()
{
for (var num = 0; num < 10; num ++)
{
var count = num; // 一度ローカル変数に代入する
buttons[num].onClick.AddListener(() => buttonClick(count)); // ローカル変数を引数にする
}
}
void buttonClick(int num)
{
Debug.Log($"{num}をクリックしたで");
}
for文の中で一度ローカル変数に代入してそれを引数として渡します。
こうすると、1のボタンを押すと「1をクリックしたで」、5のボタンを「5をクリックしたで」と表示されるようになりました。一件落着。
陥りやすい罠ですので、皆様お気をつけください!