Unity中C#类对象赋值疑问:写入JSON为何为空数组?
问题排查与修复方案
核心问题1:CarsUnlocked继承了MonoBehaviour
Unity的MonoBehaviour是组件类,不能直接用new关键字实例化,而且JsonUtility无法序列化/反序列化继承自MonoBehaviour的类型——这类对象依赖Unity的GameObject上下文,不属于普通可序列化数据类。
核心问题2:JsonUtility对顶级数组的序列化限制
JsonUtility默认不支持直接序列化顶级数组类型(比如CarsUnlocked[]),必须用包装类包裹数组才能完成正确序列化。
修复步骤
- 重构
CarsUnlocked为普通数据类,添加序列化特性与无参构造函数(JsonUtility要求序列化类型必须有无参构造):
[System.Serializable] public class CarsUnlocked { public int car; public int levelNeeded; public int moneyNeeded; public bool unlocked = false; // JsonUtility必须的无参构造函数 public CarsUnlocked() {} public CarsUnlocked(int carX, int levelNeededX, int moneyNeededX, bool unlockedX) { car = carX; levelNeeded = levelNeededX; moneyNeeded = moneyNeededX; unlocked = unlockedX; } }
- 创建数组包装类,解决
JsonUtility的序列化限制:
[System.Serializable] public class CarsUnlockedWrapper { public CarsUnlocked[] cars; }
- 修改
GameData类的序列化/反序列化逻辑:
public class GameData : MonoBehaviour { string saveFile; CarsUnlocked[] carsUnlocked = new CarsUnlocked[3]; void Awake() { saveFile = Application.persistentDataPath + "/gamedata.json"; readFile(); } public void readFile() { if (File.Exists(saveFile)) { string fileContents = File.ReadAllText(saveFile); var wrapper = JsonUtility.FromJson<CarsUnlockedWrapper>(fileContents); carsUnlocked = wrapper.cars; } else { carsUnlocked[0] = new CarsUnlocked(1,2,3,true); carsUnlocked[1] = new CarsUnlocked(1,2,3,true); carsUnlocked[2] = new CarsUnlocked(0,0,0,false); // 补全第三个元素避免null } } public void writeFile() { var wrapper = new CarsUnlockedWrapper(); wrapper.cars = carsUnlocked; // 第二个参数为true,生成格式化后的JSON方便阅读 string jsonString = JsonUtility.ToJson(wrapper, true); File.WriteAllText(saveFile, jsonString); // 遍历打印数组实际内容,替代原有的引用打印 foreach(var car in carsUnlocked) { Debug.Log($"Car ID: {car.car}, 解锁状态: {car.unlocked}"); } } }
额外说明
- 数据类必须添加
[System.Serializable]特性,否则JsonUtility无法识别。 - 原代码中
Debug.Log(carsUnlocked)只会打印数组的引用地址,无法查看实际数据,改为遍历打印才能看到真实内容。 - 初始化数组时补全第三个元素,避免序列化后出现null项。
内容的提问来源于stack exchange,提问作者MomasVII
相关产品推荐
相关产品推荐

