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
相关产品推荐
相关产品推荐

