Unity循环创建按钮时onClick参数均相同的问题求助
问题解决:Unity按钮点击传递唯一槽位ID的闭包陷阱
修正后的代码
public int inventorySize = 32; public GameObject slotPrefab; public GameObject slotHolder; public void InitiateMenu() { inventory.Initialize(); for (int i = 0; i < inventorySize; i++) { GameObject newSlot = Instantiate(slotPrefab); newSlot.transform.SetParent(slotHolder.transform, false); // 关键:在循环内创建局部变量保存当前槽位ID int currentSlotId = i; // 使用lambda绑定该局部变量 newSlot.GetComponent<Button>().onClick.AddListener(() => SlotClick(currentSlotId)); } } public void SlotClick(int slot) { Debug.Log("Inventory Slot #" + slot.ToString()); }
问题原因
这是C#闭包的典型陷阱:闭包捕获的是变量的引用,而非捕获瞬间的变量值。
你原代码中,不管用循环变量i还是curSlotId,所有按钮的委托都共享同一个变量的引用。当循环执行完毕时,这个变量的值已经变成了32(循环从0到31,最后一次自增后i等于32,触发循环退出条件),因此所有按钮点击时都会读取这个变量的最终值。
解决逻辑
在循环内部创建一个独立的局部变量(比如currentSlotId),将当前迭代的ID值赋值给它。每个循环迭代都会生成一个全新的局部变量,闭包捕获的是这个专属变量的引用,这样每个按钮的委托就能绑定到对应迭代的槽位ID,点击时自然输出正确的数值。
内容的提问来源于stack exchange,提问作者Falconeer
相关产品推荐
相关产品推荐

