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

Unity使用JsonUtility序列化对象时嵌套类信息丢失问题

问题根源

JsonUtility对继承自MonoBehaviour的类有特殊处理逻辑:当这类组件对象作为另一个类的字段存在时,默认只会序列化它的实例引用(instanceID),而非对象内部的属性数据——因为Unity将MonoBehaviour视为场景/预制体中的组件实例,而非普通数据容器。但单独序列化组件本身时,它会正常解析内部可序列化字段,这就是你遇到两种结果不一致的原因。

解决方法

方案1:剥离数据与逻辑(最推荐)

把Inventory的业务数据单独抽成一个普通可序列化类,让MonoBehaviour仅作为逻辑载体,SaveData只保存这个纯数据类的实例:

// 纯数据类,标记可序列化
[Serializable]
public class InventoryData
{
    public List<Item> database;
    public List<InventorySlot> Container;
    // 其他需要存档的字段
}

// MonoBehaviour组件只负责逻辑,数据存在InventoryData里
public class Inventory : MonoBehaviour
{
    public InventoryData data;

    void Awake()
    {
        // 初始化数据容器
        data = new InventoryData();
        // 这里可以初始化database、Container等数据
    }

    // 业务逻辑中直接操作data里的字段
}

// 存档类,只保存纯数据对象
[Serializable]
public class SaveData
{
    public InventoryData inventoryData;
    // 其他存档字段
}

// 保存逻辑
public void Save()
{
    Inventory inventory = GetComponent<Inventory>();
    SaveData saveObject = new SaveData();
    // 存数据类而非组件实例
    saveObject.inventoryData = inventory.data;
    string json = JsonUtility.ToJson(saveObject);
    // 后续保存json到文件/PlayerPrefs等
}

方案2:手动嵌入组件序列化结果(应急方案)

如果不想修改现有结构,可以先单独序列化Inventory得到完整JSON字符串,再将这个字符串作为SaveData的字段存储:

[Serializable]
public class SaveData
{
    public string inventoryJson;
    // 其他存档字段
}

// 保存逻辑
public void Save()
{
    Inventory inventory = GetComponent<Inventory>();
    SaveData saveObject = new SaveData();
    // 单独序列化Inventory得到完整数据
    saveObject.inventoryJson = JsonUtility.ToJson(inventory);
    string finalJson = JsonUtility.ToJson(saveObject);
    // 保存最终json
}

// 加载逻辑
public void Load()
{
    string finalJson = // 读取的存档JSON
    SaveData saveObject = JsonUtility.FromJson<SaveData>(finalJson);
    Inventory inventory = GetComponent<Inventory>();
    // 将单独的Inventory数据覆盖到组件实例
    JsonUtility.FromJsonOverwrite(saveObject.inventoryJson, inventory);
}
注意事项
  • 所有自定义数据类(包括InventorySlot)都必须标记[Serializable],否则JsonUtility会忽略其内部字段。
  • 避免在可序列化类中直接包含Unity的Object类型(如GameObject、Component),除非你确实需要保存实例引用而非数据。

内容的提问来源于stack exchange,提问作者Gia Bảo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:07:17