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

Unity 6格背包系统Sprite显示异常求助:变量a始终为0

6格背包系统Sprite显示异常问题排查与解决

我正在制作一个简单的6格背包系统,编写了两段C#脚本,但遇到了两个问题:

  • 执行inventory.slots[f].sprite = item[a]时,inventory.slots的Sprite始终显示数组索引0的内容
  • 变量a = itemIDs.itemID中的a始终保持为0

两段原始脚本如下:

第一段(Slots显示脚本)

Inventory inventory;
PickUp itemIDs;
public Sprite[] item;
public int a;

void Start()
{
    inventory = GameObject.FindGameObjectWithTag("Player").GetComponent<Inventory>();
    itemIDs = GameObject.FindGameObjectWithTag("Item").GetComponent<PickUp>();
}

void Update()
{
    a = itemIDs.itemID;

    for(int f = 0; f < inventory.slots.Length; f++)
    {
        if(inventory.isFull[f] == true)
        {
            inventory.slots[f].enabled = true;
            inventory.slots[f].sprite = item[a];
        }
    }
}

第二段(物品拾取脚本)

private Inventory inventory;
private Slots slots;
public int itemID = 1;
public GameObject item;

void Start()
{
    inventory = GameObject.FindGameObjectWithTag("Player").GetComponent<Inventory>();
    GameObject.FindGameObjectWithTag("Slots").GetComponent<Slots>();
}

void OnTriggerEnter(Collider other)
{
    if(other.CompareTag("Player"))
    {
        for(int f = 0; f < inventory.slots.Length; f++)
        {
            if(inventory.isFull[f] == false)
            {
                inventory.slots[f].enabled = true;
                inventory.isFull[f] = true;
                Instantiate(item, inventory.slots[f].transform, false);
                Destroy(gameObject);
                break;
            }
        }
    }
}

问题分析与解决方案

问题1:itemIDs引用失效或错误

  • 原始脚本在Start()中通过FindGameObjectWithTag("Item")获取PickUp组件,只会拿到场景中第一个带"Item"标签的物体,无法对应当前拾取的物品。
  • 物品被拾取后会执行Destroy(gameObject),此时itemIDs引用变为空,后续a = itemIDs.itemID会读取默认值0,甚至引发空引用错误。

解决:
在背包的Inventory类中新增数组存储每个格子对应的物品ID,拾取时直接将当前物品的ID存入对应格子,无需在Slots脚本中绑定固定的PickUp引用。


问题2:Update循环逻辑错误

  • 原始Update循环会遍历所有已填满的格子,统一设置为item[a],导致所有格子显示同一个Sprite,且a错误时全部显示索引0的内容。

解决:
每个格子单独存储对应的物品ID,Slots脚本根据每个格子的ID匹配对应的Sprite。


问题3:PickUp脚本冗余代码

  • Start()中的GameObject.FindGameObjectWithTag("Slots").GetComponent<Slots>()未赋值给变量,完全无效,直接删除即可。

修正后的完整代码示例

Inventory类(背包核心数据)

using UnityEngine;
using UnityEngine.UI;

public class Inventory : MonoBehaviour
{
    public Image[] slots; // 背包格子的Image组件数组
    public bool[] isFull; // 标记格子是否填满
    public int[] slotItemIDs; // 新增:存储每个格子对应的物品ID,-1表示空

    void Awake()
    {
        // 初始化物品ID数组
        slotItemIDs = new int[slots.Length];
        for (int i = 0; i < slotItemIDs.Length; i++)
        {
            slotItemIDs[i] = -1;
        }
    }
}

PickUp类(物品拾取逻辑)

using UnityEngine;

public class PickUp : MonoBehaviour
{
    private Inventory inventory;
    public int itemID = 1; // 当前物品的ID,需在Inspector中设置
    public GameObject itemPrefab; // 背包中显示的物品预制体

    void Start()
    {
        inventory = GameObject.FindGameObjectWithTag("Player").GetComponent<Inventory>();
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            // 遍历背包找空格子
            for (int f = 0; f < inventory.slots.Length; f++)
            {
                if (!inventory.isFull[f])
                {
                    inventory.isFull[f] = true;
                    inventory.slotItemIDs[f] = itemID; // 记录当前物品ID到格子
                    Instantiate(itemPrefab, inventory.slots[f].transform, false);
                    Destroy(gameObject);
                    break;
                }
            }
        }
    }
}

SlotsDisplay类(背包格子显示逻辑)

using UnityEngine;
using UnityEngine.UI;

public class SlotsDisplay : MonoBehaviour
{
    private Inventory inventory;
    public Sprite[] itemSprites; // 所有物品的Sprite列表,索引需与itemID对应

    void Start()
    {
        inventory = GameObject.FindGameObjectWithTag("Player").GetComponent<Inventory>();
    }

    void Update()
    {
        // 遍历每个格子更新显示
        for (int f = 0; f < inventory.slots.Length; f++)
        {
            if (inventory.isFull[f])
            {
                int currentItemID = inventory.slotItemIDs[f];
                // 检查ID是否有效,防止索引越界
                if (currentItemID >= 0 && currentItemID < itemSprites.Length)
                {
                    inventory.slots[f].enabled = true;
                    inventory.slots[f].sprite = itemSprites[currentItemID];
                }
            }
            else
            {
                inventory.slots[f].enabled = false; // 空格子隐藏Sprite
            }
        }
    }
}

额外注意事项

  • 在Inspector中给Inventory组件的slots、isFull、slotItemIDs数组设置长度为6。
  • itemSprites数组需按itemID顺序赋值,比如itemID=1对应数组索引1的Sprite。
  • 每个拾取物品的PickUp组件中,itemID要设置正确的值(比如第一个物品设1,第二个设2)。

内容的提问来源于stack exchange,提问作者Meyji Kazuto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:35:42