Unity中如何基于Toggle结构体数组判断被修改的开关并获取其索引
Unity Toggle数组监听获取触发索引的实现方案
问题根源
你现有代码的核心问题是C#循环中匿名委托的闭包变量捕获问题:循环变量i在整个循环周期内是同一个引用,所有匿名委托捕获的都是这同一个i,等到监听触发时i已经循环结束等于toggles.Length,自然拿不到正确索引。
最优解决方案(推荐)
在循环内声明临时变量存储当前索引,规避闭包捕获问题,直接把索引传给回调函数,无需额外遍历匹配,性能最高。
修改后的完整代码如下:
using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; public class ToggleData : MonoBehaviour { [System.Serializable] public struct toggleInfo { public Toggle toggle; public TextMeshProUGUI toggleText; } public toggleInfo[] toggles; // Start is called before the first frame update void Start () { for (int i = 0; i < toggles.Length; i++) { // 循环内声明临时变量存储当前索引,每个迭代的临时变量都是独立的,不会被闭包共享 int currentIndex = i; // 绑定监听时直接把索引和Toggle自带的开关状态参数传给回调 toggles[i].toggle.onValueChanged.AddListener ((isOn) => ToggleValueChanged(currentIndex, isOn)); } } // 回调直接接收触发的索引和当前开关状态 void ToggleValueChanged (int index, bool isOn) { Debug.Log ($"触发的Toggle索引:{index},当前开关状态:{isOn}"); // 可直接通过索引获取对应Toggle的所有关联数据 Toggle triggerToggle = toggles[index].toggle; TextMeshProUGUI triggerText = toggles[index].toggleText; } }
备选解决方案(适合少量Toggle场景)
如果你不想修改回调函数的参数结构,也可以在回调内遍历数组匹配Toggle实例拿到索引,缺点是每次触发都要遍历,Toggle数量多时性能略低:
void ToggleValueChanged (Toggle change) { for (int i = 0; i < toggles.Length; i++) { if (toggles[i].toggle == change) { Debug.Log ($"匹配到的Toggle索引:{i}"); break; } } }
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

