0

クリック リスナーを追加したいボタンのリストをコードに追加しています。

リスナーを追加できました。問題は、リスナーを呼び出したボタンを知りたいということです。

次の方法を試しましたが、リスナーに渡される値は常に同じです。

foreach (...)
{
    var button = (Button)GameObject.Instantiate(...);

    packIndex++;

    button.onClick.AddListener(() => this.OnButtonClick(packIndex));
}

public void OnButtonClick(int idx)
{
    // idx is always the latest value in the above loop
}

TL;DR

ボタンクリックリスナーから発信者を見つけるにはどうすればよいですか?

4

2 に答える 2

1

あなたはほとんどそれを持っています。packIndexインデックスを保存するには、 for ループ内でのコピーを作成して packIndex 変数を「キャプチャ」する必要があります。この「for ループでのクロージャ」現象の適切な説明は、こちらで確認できます

次のコードが機能するはずです。

foreach (...)
{
    var button = (Button)GameObject.Instantiate(...);

    packIndex++;
    var packIndexCopy = packIndex;

    button.onClick.AddListener(() => this.OnButtonClick(packIndexCopy));
}

public void OnButtonClick(int idx)
{
    // idx is always the latest value in the above loop
}

@Nain による回答も機能することに注意してください。その場合、「ボタン」オブジェクトAddListener(() => this.OnButtonClick(button));は foreach ループで毎回作成される新しいオブジェクトを参照するため、コンパイラはOnButtonClickハンドラーをその「新しい」コピーに正しくバインドします。実際、Buttonオブジェクトを直接渡すと少しきれいに感じますが、それはコードの残りの部分に依存します。

クロージャーに慣れていない場合 (これは非常に紛らわしく、理解するのに長い時間がかかります!)、この記事には適切な説明があります。

PSこれをテストするために小さなコンポーネントを作成しました。役立つ場合に備えて、その要点を次に示します。

于 2015-08-16T17:49:25.323 に答える
1

これを試して

var button = (Button)GameObject.Instantiate(...);
packIndex++;
button.name = "Button" + packIndex;
button.onClick.AddListener(() => this.OnButtonClick(button));

public void OnButtonClick(Button button)
{
// idx is always the latest value in the above loop
}
于 2015-08-16T17:36:04.327 に答える