動的にボタンにデータを持った機能を加える


※)15.06.06 一番下に追記あり

動的にボタンを作成したときに、それぞれのボタンに対して情報を分けた処理をさせたい。
ラムダ式でパラメータ渡そうと思ったけどうまく行かない。

[unitycsharp]
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);
}
}
[/unitycsharp]

どうもローカル変数を参照しているみたい。
なので、メソッドを分けて引数で数字を渡すとうまくいった。

[unitycsharp]
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);
}
}
[/unitycsharp]

余計なメソッドを作らずに、Actionを作って実行するなら
[unitycsharp]
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);
}
}
[/unitycsharp]

これでいいのかな?
もっといいやり方があるような気がするけど…

追記 15.06.06
ローカル変数を新たに作って、そちらへ代入する方法でもできた。。
以前試したらうまくいかなかったんだけどなぁ。。。
[unitycsharp]
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);
});
}
}
}
[/unitycsharp]

“動的にボタンにデータを持った機能を加える” への1件のコメント

  1. ももせ より:

    ローカル変数を参照してしまう問題で困っていました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です