Unity循环里面给按钮添加绑定事件

软件:
全方位数据报表
许可分析

许可分析

免费体验
识别闲置、及时回收
许可优化

许可优化

免费体验
多维度智能分析
许可分析

许可分析

免费体验
减少成本、盘活许可
许可优化

许可优化

免费体验

前言

在软件开发中,经常遇到一些看似直觉但实则暗藏陷阱的问题,这些问题往往让人在第一次接触或理解时感到困惑。本文将聚焦于一个在Unity引擎中开发过程中遇到的具体问题,即使用foreach循环对多个按钮绑定点击事件时,意想不到的行为表现。这样的情境可以帮助开发者及其同行更好地理解内存管理与多线程同步的复杂性,从而提升代码的鲁棒性和效率。

问题描述

考虑以下代码片段试图通过foreach循环来给一组按钮分别绑定点击事件,以对应显示不同面板:

```csharp


using UnityEngine;


using UnityEngine.UI;


public class TestBtn : MonoBehaviour


{


public Button[] AllBtn;

欢迎浏览: Unity循环里面给按钮添加绑定事件


public GameObject[] ALLPanel;


void Start()


{


for (int i = 0; i < AllBtn.Length; i++)


{

AllBtn[i].onClick.AddListener(() => BtnEvent(i));

}


}


private void BtnEvent(int index)


{


Debug.Log(index);

for (int i = 0; i < ALLPanel.Length; i++)

{


ALLPanel[i].SetActive(false);


}


ALLPanel[index].SetActive(true);


}


}


```

当运行上述代码时,却发现程序出现错误:“数组索引超出范围”,调试工具显示传递给`BtnEvent`方法的索引值为3。乍一看,代码已清晰地针对各按钮分配了直觉上的单一响应,但实际结果为何与期望形成明显差异?

分析过程

深入分析我们发现的根本问题在于循环机制以及存储于循环内部的临时变量`i`的生命周期与传递的效率。每轮迭代内静态定义`i`只是被初始化一次,且在循环终止时将其设置为循环长度减一的值。此后,无论是定位目标按钮还是选择性激活目标面板,内部变量`i`被使用多次,其值固定为最终循环迭代的`i`值,即3。

直观地,在每次ButtononClick事件的调用中,实际绑定到方法`BtnEvent`的对象(实质上是来自`AllBtn`数组的一个成员)正引用处于循环末尾时自动提升的同一个临时变量。然而,预期的行为是每个按钮事件映射到其特定的面板激活逻辑,但因为所有按钮事实上都引用了相同的`i`值,生成的响应便只符合最后一次迭代的结果,而非逼近的对象所期望的特定面板。

解决方法

上述问题的症结在于循环机制被误解,导致局部变量在事件回调中并不如预期那样重置。解决方案的关键在于,在每次循环中为每个按钮事件绑定提供一个唯一、全局的标识符,以确保每次调用的边界清晰。

一个有效且简单的方法是在事件绑定中重复使用相同逻辑时引入临时变量,确保每次解析索引时使用当前迭代的`i`值,而不仅仅是最后一次迭代后被赋值的`i`值:

```csharp


using UnityEngine;


using UnityEngine.UI;


public class TestBtn : MonoBehaviour


{


public Button[] AllBtn;


public GameObject[] ALLPanel;


void Start()


{


for (int i = 0; i < AllBtn.Length; i++)


{


int temp = i;

AllBtn[i].onClick.AddListener(() => BtnEvent(temp));

}


}


private void BtnEvent(int index)


{


Debug.Log(index);

for (int i = 0; i < ALLPanel.Length; i++)

{


ALLPanel[i].SetActive(false);


}


ALLPanel[index].SetActive(true);


}


}


```

通过引入额外的变量`temp`作为循环过程中的隔离标识符,我们确保了每次点击按钮事件触发时传入`s`方法的索引参数均取自循环迭代的当前值,而非循环结束时的固定值。这样,问题得以妥善解决,多个按钮事件的绑定行为恢复正常预期,每个按钮对应准确激活其预定的面板。

index-foot-banner-pc index-foot-banner-phone

点击一下 免费体验万千客户信任的许可优化平台

与100+大型企业一起,将本增效

与100+大型企业一起,将本增效

申请免费体验 申请免费体验