You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity操作ItemSlot数组时出现Null Reference错误的异常问题

问题原因与解决方案

核心问题

  1. 自定义类未标记可序列化:你的ItemSlot类没有添加[System.Serializable]属性,Unity无法正确序列化这个自定义类型。编辑器选中Inventory物体时会临时生成空实例用于显示,但取消选中后这些临时实例会被回收,数组元素变回null。
  2. 数组元素未初始化: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:43:23