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

