Unity动态滚动视图预制体异常:超3个或删单个报MissingReferenceException
问题根源与修复方案
核心问题分析
- 无效引用残留:
JLID列表在销毁预制体后未同步清空,导致列表中保留已被销毁的GameObject引用,后续访问时触发MissingReferenceException。 - 父物体不匹配:代码销毁的是
ScrollViewContent的子物体,但预制体实例化到PrefabParent下,旧物体无法被正确清理,新旧实例堆积引发异常。 - 重复获取组件:
Update中每次都重新获取JLList,效率低下且易因原组件列表修改导致引用不稳定。
具体修复步骤
- 同步清空引用列表:销毁预制体后立刻清空
JLID,避免残留无效引用。 - 统一父物体:将预制体实例化到
ScrollViewContent下,与销毁逻辑的父物体保持一致,确保旧物体被彻底清理。 - 优化组件获取:初始化时仅获取一次
AddJL组件,后续直接访问其JLList,减少重复调用带来的不稳定。 - 增加空值判断:在
CheckForChange中判断JLList是否为空,避免空列表触发无效生成逻辑。
修正后的完整代码
private List<JL> JLList; public List<GameObject> JLID; public GameObject ButtonPrefab; public GameObject JLMenuManager; public GameObject ScrollViewContent; private AddJL _addJLComponent; private void Start() { _addJLComponent = JLMenuManager.GetComponent<AddJL>(); JLID = new List<GameObject>(); } private void Update() { JLList = _addJLComponent.JLList; CheckForChange(); } private void GenerateOptions() { foreach (Transform child in ScrollViewContent.transform) { Destroy(child.gameObject); } JLID.Clear(); for (int i = 0; i < JLList.Count; i++) { GameObject newJLOption = Instantiate(ButtonPrefab, ScrollViewContent.transform); JLID.Add(newJLOption); int JLIndex = i; newJLOption.GetComponent<Button>().onClick.AddListener(() => LoadJLOptions(JLIndex)); } } private void LoadJLOptions(int JLIndex) { SendMessage("SetJL", JLIndex); Debug.Log(JLIndex); } private void CheckForChange() { if (JLList == null) return; int allJLOptions = ScrollViewContent.transform.childCount; if (allJLOptions != JLList.Count) { GenerateOptions(); } }
内容的提问来源于stack exchange,提问作者user19518133
相关产品推荐
相关产品推荐

