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

Unity中Crafting System合成系统无报错无法运行问题排查

Unity 简易Crafting合成系统无报错失效修复

核心故障原因

代码无语法报错但功能失效是4处逻辑问题导致,均属于静默失效类问题,不会主动抛出运行时错误:

  • 索引使用错误:内层匹配循环中错误使用背包遍历索引z去取配方需求数组Item的元素,配方需求数组的正确遍历索引是外层循环的i,索引错位直接导致匹配逻辑完全失效。
  • 组件类型不匹配:项目使用SCItem类型的ScriptableObject存储物品数据,但代码中获取物品组件时写的是GetComponent<Item>(),取到的组件永远为null,和SCItem类型的配方数据对比永远返回false。
  • 重复计数漏洞:原有逻辑没有标记已匹配的背包物品,当背包内仅存在1个需求材料时,会被多次循环计数,导致材料数量不足时也会误判为满足合成条件。
  • 缺失合法性校验:代码没有对关键引用(ItemManager、成品预制体、配方数组长度)做判空和配置校验,配置漏拖、对象找不到时会直接静默退出逻辑,没有任何提示。

Inspector配置参考

Unity Inspector配置截图

修复后完整代码

public class CraftingItem: MonoBehaviour
{
  public int RequiredItems;
  public SCItem[] RequiredItemList;
  private Transform itemManagerTransform;
  public GameObject FinishItem;
  private readonly List<SCItem> _inventoryItemCache = new List<SCItem>();

  public void Start(){
    GameObject itemManagerGo = GameObject.FindWithTag("ItemManager");
    if (itemManagerGo != null)
    {
        itemManagerTransform = itemManagerGo.transform;
    }
    // 配置错误时直接打印日志,避免静默失效
    if (RequiredItemList.Length != RequiredItems)
    {
        Debug.LogError($"合成配置错误:{gameObject.name}的需求物品数量与配方数组长度不一致", this);
    }
  }

  public void CheckForRequiredItems(){
    // 前置校验不满足直接返回
    if (itemManagerTransform == null || FinishItem == null || RequiredItemList.Length != RequiredItems)
    {
        return;
    }

    int itemsInManager = itemManagerTransform.childCount;
    if(itemsInManager < RequiredItems) return;

    // 刷新当前背包物品缓存
    _inventoryItemCache.Clear();
    for(int z = 0; z < itemsInManager; z++){
        // 替换为你物品预制体上实际挂的、持有SCItem引用的组件名
        ItemSlot itemOnPlayer = itemManagerTransform.GetChild(z).GetComponent<ItemSlot>();
        if (itemOnPlayer != null && itemOnPlayer.itemData != null)
        {
            _inventoryItemCache.Add(itemOnPlayer.itemData);
        }
    }

    int matchedCount = 0;
    List<SCItem> usedItems = new List<SCItem>();
    // 遍历所有需求材料
    for(int i = 0; i < RequiredItems; i++){
        SCItem target = RequiredItemList[i];
        // 找背包里未被使用的对应材料
        for(int z = 0; z < _inventoryItemCache.Count; z++){
            if(_inventoryItemCache[z] == target && !usedItems.Contains(_inventoryItemCache[z])){
                matchedCount++;
                usedItems.Add(_inventoryItemCache[z]);
                break;
            }
        }
    } 

    if(matchedCount >= RequiredItems){
        Instantiate(FinishItem, transform.position, transform.rotation);
        // 若需要合成后消耗材料,在此处遍历usedItems对应销毁背包内的物品物体即可
    }
  }
}

适配说明

代码中ItemSlot为示例组件名,你需要将其替换为自己项目中实际挂载在背包物品物体上、持有SCItem类型数据引用的MonoBehaviour组件名,确保能正确读取到每个背包物品对应的ScriptableObject数据。配置时需保证RequiredItems数值与RequiredItemList数组长度一致,数组内按需求拖入对应材料的SCItem资产即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:45:40