Unity场景切换时Inventory报MissingReferenceException故障求助
解决Unity Inventory系统跨场景MissingReferenceException及物品持久化问题
问题根源
场景切换时,旧场景里的UI元素(比如InventoryItemUI绑定的Image组件)会被销毁,但你的InventoryController如果是跨场景保留的单例,大概率还攥着旧场景的UI引用——调用ResetData时自然会触发已销毁对象的访问异常。注释掉初始物品添加逻辑后,没触发对旧UI的操作,所以错误消失,但同时也丢了物品跨场景保存的能力。
解决方案
1. 修复UI引用丢失
场景加载后重新绑定UI
给InventoryController加个场景加载完成的监听,每次切场景后重新获取当前场景的UI实例,替换掉旧的销毁引用:private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { // 重新查找并初始化当前场景的物品槽UI RefreshInventoryUIReferences(); }其中
RefreshInventoryUIReferences()负责遍历当前场景的InventoryItemUI组件,重新绑定内部的Image、文本等引用。给
ResetData加安全判断
修改InventoryItemUI的ResetData方法,先检查组件是否存活,再执行逻辑:public void ResetData() { if (this == null || !gameObject.activeInHierarchy) return; // 原有清空逻辑 itemImage.sprite = null; itemImage.enabled = false; countText.text = string.Empty; }
2. 实现物品跨场景持久化
- 用单例存数据,别绑UI
让InventoryController做跨场景不销毁的单例,把物品数据存在独立的列表里,不要依赖UI组件保存数据:public class InventoryController : MonoBehaviour { public static InventoryController Instance; public List<ItemData> inventoryItems = new List<ItemData>(); private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } // 添加物品只操作数据列表 public void AddItem(ItemData item) { inventoryItems.Add(item); // 通知当前场景的UI更新 SyncInventoryToUI(); } // 把数据同步到当前场景的UI上 private void SyncInventoryToUI() { var currentSlots = FindObjectsOfType<InventoryItemUI>(); for (int i = 0; i < currentSlots.Length; i++) { if (i < inventoryItems.Count) { currentSlots[i].SetItemData(inventoryItems[i]); } else { currentSlots[i].ResetData(); } } } } - 调整初始物品添加逻辑
原来的初始物品循环,直接往inventoryItems列表里加数据就行,不要直接操作UI。等场景加载完成后,调用SyncInventoryToUI()把数据渲染到当前场景的UI上。
3. 额外提醒
- 别给
InventoryItemUI设置DontDestroyOnLoad,UI是属于场景的,切场景时该销毁就销毁,新场景重新生成就行。 - 测试时重点看两点:切场景后
inventoryItems列表数据是否保留,UI组件是不是当前场景的新实例。
内容的提问来源于stack exchange,提问作者Elin Rafferty
相关产品推荐
相关产品推荐

