Unity操作ItemSlot数组时出现Null Reference错误的异常问题
问题原因与解决方案
核心问题
- 自定义类未标记可序列化:你的
ItemSlot类没有添加[System.Serializable]属性,Unity无法正确序列化这个自定义类型。编辑器选中Inventory物体时会临时生成空实例用于显示,但取消选中后这些临时实例会被回收,数组元素变回null。 - 数组元素未初始化:
Start()里仅创建了长度为10的ItemSlot[]数组容器,但每个数组元素都是null,没有实际创建ItemSlot实例。访问null对象的字段自然会触发空引用错误。
修复步骤
1. 标记ItemSlot为可序列化类
给ItemSlot类添加[System.Serializable],让Unity能正确处理它的序列化:
[System.Serializable] public class ItemSlot { [SerializeField] public string ItemName; [SerializeField] public ItemsSO ItemProperty; [SerializeField] public int ItemAmount; }
2. 正确初始化数组元素
修改Start()方法,循环为每个数组索引创建ItemSlot实例,确保每个位置都有有效的对象:
[SerializeField] public ItemSlot[] playerInventory; private void Start() { playerInventory = new ItemSlot[10]; // 为每个槽位创建ItemSlot实例并初始化默认值 for (int i = 0; i < playerInventory.Length; i++) { playerInventory[i] = new ItemSlot(); playerInventory[i].ItemName = ""; playerInventory[i].ItemAmount = 0; } }
3. 增加安全检查(可选但推荐)
在访问数组元素的字段前,先检查索引合法性与元素是否为null,避免意外报错:
public void MoveItemInPlayerInventoryFromPlayerInventory(ItemSlot movingItem, int inventoryIndex) { // 检查索引是否合法 if (inventoryIndex < 0 || inventoryIndex >= playerInventory.Length) { Debug.LogError("无效的背包索引:" + inventoryIndex); return; } int movingItemIndex = Array.IndexOf(playerInventory, movingItem); // 检查要移动的物品是否在数组中 if (movingItemIndex == -1) { Debug.LogError("要移动的物品不在背包数组中"); return; } // 检查目标槽位是否初始化 if (playerInventory[inventoryIndex] == null) { Debug.LogError("目标槽位未初始化"); return; } Debug.LogError($"Item Drag At Inventory Index : {inventoryIndex} \nItem Checking : !{playerInventory[inventoryIndex].ItemName}! "); // 目标槽位为空(物品属性为null) if (playerInventory[inventoryIndex].ItemProperty == null) { playerInventory[inventoryIndex] = playerInventory[movingItemIndex]; // 原槽位重新创建空实例,避免后续访问null playerInventory[movingItemIndex] = new ItemSlot(); playerInventory[movingItemIndex].ItemName = ""; playerInventory[movingItemIndex].ItemAmount = 0; } else { // 交换物品 ItemSlot temp = playerInventory[inventoryIndex]; playerInventory[inventoryIndex] = playerInventory[movingItemIndex]; playerInventory[movingItemIndex] = temp; } InventoryUIManager.Instance.ShowItemPreviewAtInventory(); }
原理说明
- 标记
[System.Serializable]后,Unity会将ItemSlot类型视为可序列化对象,编辑器和运行时都能正确维护数组中的元素实例。 - 初始化每个数组元素为
ItemSlot实例后,无论是否选中物体,数组中都不会有null元素,访问字段时就不会触发空引用错误。
内容的提问来源于stack exchange,提问作者Kno_X
相关产品推荐
相关产品推荐

