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

Unity 2D游戏背包系统报错:Input string was not in a correct format

Unity背包系统点击物品触发FormatException问题解决

问题详情

开发2D游戏时跟着教程实现背包系统,点击背包物品触发以下错误:

FormatException: Input string was not in a correct format. 
System.Number.ThrowOverflowOrFormatException (System.Boolean overflow, System.String overflowResourceKey) (at <3ead76266f1846f192cd3a42f27e86c3>:0) 
System.Number.ParseInt32 (System.ReadOnlySpan`1[T] value, System.Globalization.NumberStyles styles, System.Globalization.NumberFormatInfo info) (at <3ead76266f1846f192cd3a42f27e86c3>:0) 
System.Int32.Parse (System.String s) (at <3ead76266f1846f192cd3a42f27e86c3>:0)

错误指向代码行:currentID = int.Parse(es.currentSelectedGameObject.name);

当前代码实现如下:

public void SelectObject()
{
    if (currentID == -1)
    {
        currentID = int.Parse(es.currentSelectedGameObject.name);
        currentItem = CopyInventoryItem(items[currentID]);
        movingObject.gameObject.SetActive(true);
        movingObject.GetComponent<Image>().sprite = data.items[currentItem.id].image;

        AddItem(currentID, data.items[0], 0);
    }
    else
    {
        AddInventoryItem(currentID, items[int.Parse(es.currentSelectedGameObject.name)]);
        
        AddInventoryItem(int.Parse(es.currentSelectedGameObject.name), currentItem);
        currentID = -1;
        
        movingObject.gameObject.SetActive(false);
    }
}

错误原因

int.Parse()要求输入的字符串必须是纯整数格式,但当前选中的es.currentSelectedGameObject的名字不符合这个要求(比如带有前缀、后缀,或者不是数字),导致无法完成转换,抛出FormatException。

解决方案

1. 检查并修正物品格子命名

确保所有背包物品格子的GameObject名字为纯数字(如"0"、"1"、"2"),不要包含任何额外字符(比如"ItemSlot_0"、"Slot1"这类命名都不行)。

2. 替换为安全的转换方法

用int.TryParse()替代int.Parse(),它不会直接崩溃,还能输出错误日志帮助排查问题。修改后的代码如下:

public void SelectObject()
{
    if (currentID == -1)
    {
        if (!int.TryParse(es.currentSelectedGameObject.name, out currentID))
        {
            Debug.LogError($"对象名 {es.currentSelectedGameObject.name} 无法转换为整数,请检查格子命名!");
            return;
        }
        currentItem = CopyInventoryItem(items[currentID]);
        movingObject.gameObject.SetActive(true);
        movingObject.GetComponent<Image>().sprite = data.items[currentItem.id].image;

        AddItem(currentID, data.items[0], 0);
    }
    else
    {
        if (!int.TryParse(es.currentSelectedGameObject.name, out int targetID))
        {
            Debug.LogError($"对象名 {es.currentSelectedGameObject.name} 无法转换为整数,请检查格子命名!");
            return;
        }
        AddInventoryItem(currentID, items[targetID]);
        AddInventoryItem(targetID, currentItem);
        currentID = -1;
        
        movingObject.gameObject.SetActive(false);
    }
}

3. 优化:不依赖GameObject名字存储ID

依赖名字传ID是脆弱的做法,推荐给每个物品格子挂载一个专用脚本存储ID:

// 创建SlotID脚本并挂载到每个物品格子上
public class SlotID : MonoBehaviour
{
    public int slotID; // 在Inspector中设置对应的格子ID
}

然后修改SelectObject方法,通过脚本获取ID:

public void SelectObject()
{
    var selectedSlot = es.currentSelectedGameObject.GetComponent<SlotID>();
    if (selectedSlot == null)
    {
        Debug.LogError("选中的格子未挂载SlotID脚本!");
        return;
    }
    
    if (currentID == -1)
    {
        currentID = selectedSlot.slotID;
        currentItem = CopyInventoryItem(items[currentID]);
        movingObject.gameObject.SetActive(true);
        movingObject.GetComponent<Image>().sprite = data.items[currentItem.id].image;

        AddItem(currentID, data.items[0], 0);
    }
    else
    {
        int targetID = selectedSlot.slotID;
        AddInventoryItem(currentID, items[targetID]);
        AddInventoryItem(targetID, currentItem);
        currentID = -1;
        
        movingObject.gameObject.SetActive(false);
    }
}

这种方法彻底避免了命名格式问题,后续维护也更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:06:02