動的にボタンにデータを持った機能を加える
※)15.06.06 一番下に追記あり
動的にボタンを作成したときに、それぞれのボタンに対して情報を分けた処理をさせたい。
ラムダ式でパラメータ渡そうと思ったけどうまく行かない。
using UnityEngine;
using UnityEngine.UI;
using System;
public class Test : MonoBehaviour {
// ボタンのプレハブ
public GameObject buttonPrefab;
// Start.
void Start () {
for (int i = 0; i < 10; ++i) {
GameObject buttonGO = (GameObject)Instantiate(this.buttonPrefab);
buttonGO.transform.SetParent(this.transform, false);
Button button = buttonGO.GetComponent<Button>();
button.onClick.AddListener(() => {
this.DoSomething(i);
});
}
}
// なにか処理する
void DoSomething(int num) {
print(num);
}
}
どうもローカル変数を参照しているみたい。
なので、メソッドを分けて引数で数字を渡すとうまくいった。
using UnityEngine;
using UnityEngine.UI;
using System;
public class Test : MonoBehaviour {
// ボタンのプレハブ
public GameObject buttonPrefab;
// Start.
void Start () {
for (int i = 0; i < 10; ++i) {
GameObject buttonGO = (GameObject)Instantiate(this.buttonPrefab);
buttonGO.transform.SetParent(this.transform, false);
Button button = buttonGO.GetComponent<Button>();
this.AddButtonEvent(button, i);
}
}
// ボタンに機能を付与する
void AddButtonEvent(Button button, int num) {
button.onClick.AddListener(() => {
this.DoSomething(num);
});
}
// なにか処理する
void DoSomething(int num) {
print(num);
}
}
余計なメソッドを作らずに、Actionを作って実行するなら
using UnityEngine;
using UnityEngine.UI;
using System;
public class Test : MonoBehaviour {
// ボタンのプレハブ
public GameObject buttonPrefab;
// Start.
void Start () {
// ボタンに機能を付与する
Action<Button, int> addButtonEvent = (Button button, int num) => {
button.onClick.AddListener(() => {
this.DoSomething(num);
});
};
for (int i = 0; i < 10; ++i) {
GameObject buttonGO = (GameObject)Instantiate(this.buttonPrefab);
buttonGO.transform.SetParent(this.transform, false);
Button button = buttonGO.GetComponent<Button>();
addButtonEvent(button, i);
}
}
// なにか処理する
void DoSomething(int num) {
print(num);
}
}
これでいいのかな?
もっといいやり方があるような気がするけど…
追記 15.06.06
ローカル変数を新たに作って、そちらへ代入する方法でもできた。。
以前試したらうまくいかなかったんだけどなぁ。。。
using UnityEngine;
using UnityEngine.UI;
using System;
public class Test : MonoBehaviour {
// ボタンのプレハブ
public GameObject buttonPrefab;
// Start.
void Start () {
for (int i = 0; i < 10; ++i) {
GameObject buttonGO = (GameObject)Instantiate(this.buttonPrefab);
buttonGO.transform.SetParent(this.transform, false);
Button button = buttonGO.GetComponent<Button>();
// ここで新たな変数へ代入する
int j = i;
button.onClick.AddListener(() => {
print(j);
});
}
}
}
ローカル変数を参照してしまう問題で困っていました。