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

Unity ScriptableObject库存系统遇CS0120/CS0117错误求助

解决PlayerSaveData嵌套类成员访问的CS0120/CS0117错误

错误原因分析

你遇到的两个错误本质是对嵌套类的类型与实例混淆,以及成员访问规则的误解:

  • CS0120:需要对象引用才能访问非静态成员——你直接通过嵌套类的类型(PlayerSaveData.Inventory)访问实例成员inventoryMain,而非通过类的实例。
  • CS0117:类型不包含定义——因为inventoryMain是Inventory类的实例成员,不是静态成员,所以PlayerSaveData.Inventory这个类型本身没有该成员。

核心修正思路

嵌套类PlayerSaveData.Inventory只是一个类型定义,你需要先拿到PlayerSaveData的实例,再访问该实例中属于Inventory类型的成员变量,最终才能获取到inventoryMain。

代码修正示例

1. 确认PlayerSaveData的结构(检查访问修饰符与实例成员)

确保你的PlayerSaveData中正确定义了Inventory的实例,且inventoryMain的访问修饰符为public/internal:

using UnityEngine;
using System.Collections.Generic;

[CreateAssetMenu(fileName = "PlayerSaveData", menuName = "Save Data/Player")]
public class PlayerSaveData : ScriptableObject
{
    // 定义嵌套的Inventory类
    public class Inventory
    {
        // 确保成员是public,外部可访问
        public List<InventorySlot> inventoryMain = new List<InventorySlot>();
        // 其他库存相关成员...
    }

    public class Wormhole
    {
        // 虫洞相关成员...
    }

    // 关键:定义Inventory类的实例(而非仅定义类型)
    public Inventory playerInventory = new Inventory();
}

// 确保InventorySlot的定义也可被外部访问
public class InventorySlot
{
    public string itemId;
    public int count;
    // 其他槽位成员...
}

2. 在CraftingRecipes中正确访问实例成员

通过PlayerSaveData的实例(而非类型)访问其内部的Inventory实例,再获取inventoryMain:

using UnityEngine;

public class CraftingRecipes : MonoBehaviour
{
    // 在Inspector面板中拖入你的PlayerSaveData实例
    public PlayerSaveData playerSaveData;

    public bool CanCraft()
    {
        // 正确路径:PlayerSaveData实例 → Inventory实例 → inventoryMain成员
        var mainInventorySlots = playerSaveData.playerInventory.inventoryMain;
        
        // 后续判断材料是否充足的逻辑...
        return mainInventorySlots.Exists(slot => slot.itemId == "Wood" && slot.count >= 2);
    }

    public void Craft()
    {
        var mainInventory = playerSaveData.playerInventory.inventoryMain;
        
        // 移除材料逻辑
        var woodSlot = mainInventory.Find(slot => slot.itemId == "Wood");
        if (woodSlot != null)
        {
            woodSlot.count -= 2;
            if (woodSlot.count <= 0)
                mainInventory.Remove(woodSlot);
        }

        // 添加成品逻辑
        mainInventory.Add(new InventorySlot { itemId = "Plank", count = 1 });
    }
}

额外排查点

  • 如果你的inventoryMain是private修饰,改为public或通过属性(public List<InventorySlot> InventoryMain => inventoryMain;)暴露。
  • 若你确实需要静态访问(不推荐,会导致多玩家数据冲突),可将inventoryMain改为静态成员:public static List<InventorySlot> inventoryMain;,此时访问方式为PlayerSaveData.Inventory.inventoryMain。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:39:27