動的にボタンにデータを持った機能を加える
※)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); }); } } }
ローカル変数を参照してしまう問題で困っていました。