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

Unity/C#:ScriptableObject数组存储JSON仅保留最后一项问题排查

问题分析与解决方案

嘿,我一眼就瞅出你代码里的问题啦!你在循环保存每个ShopItem的时候,每次都创建同一个文件skins_save.txt——File.Create()方法如果遇到已存在的文件,会直接覆盖掉原有内容,所以循环跑完后,自然就只剩最后一个对象的数据咯。

下面给你两种靠谱的解决思路:

方案1:序列化整个数组(推荐)

JsonUtility默认没法直接序列化数组,所以我们可以给数组套个包装类,一次性序列化整个集合,这样既高效又避免覆盖问题:

首先创建一个序列化的包装类:

[Serializable]
public class ShopItemCollection
{
    public ShopItem[] items;
}

然后修改你的SaveGame方法:

public void SaveGame() 
{ 
    string saveDir = Application.persistentDataPath + "/game_save";
    string dataDir = saveDir + "/data";
    
    // 确保目录存在
    if (!Directory.Exists(saveDir)) 
    { 
        Directory.CreateDirectory(saveDir); 
    } 
    if (!Directory.Exists(dataDir)) 
    { 
        Directory.CreateDirectory(dataDir); 
    } 

    string filePath = dataDir + "/skins_save.txt";
    BinaryFormatter bf = new BinaryFormatter();

    // 把数组装进包装类
    ShopItemCollection collection = new ShopItemCollection();
    collection.items = shopitems;

    // 序列化整个集合为JSON
    string json = JsonUtility.ToJson(collection, prettyPrint: true);

    // 使用using语句自动管理文件流,不用手动Close
    using (FileStream file = File.Create(filePath))
    {
        bf.Serialize(file, json);
    }
}

方案2:给每个对象单独命名文件

如果你确实需要每个ShopItem存成单独的文件,那只要给每个文件加个索引后缀,避免重名覆盖就行:

public void SaveGame() 
{ 
    string saveDir = Application.persistentDataPath + "/game_save";
    string dataDir = saveDir + "/data";
    
    if (!Directory.Exists(saveDir)) 
    { 
        Directory.CreateDirectory(saveDir); 
    } 
    if (!Directory.Exists(dataDir)) 
    { 
        Directory.CreateDirectory(dataDir); 
    } 

    BinaryFormatter bf = new BinaryFormatter();
    for (int i = 0; i < shopitems.Length; i++) 
    { 
        ShopItem si = shopitems[i]; 
        // 给文件名加上索引区分
        string filePath = dataDir + $"/skins_save_{i}.txt";
        using (FileStream file = File.Create(filePath))
        {
            var json = JsonUtility.ToJson(si); 
            bf.Serialize(file, json); 
        }
    } 
}

另外补充个小建议:用using语句包裹FileStream是更好的习惯,它会在代码块结束后自动关闭并释放文件资源,比手动调用Close()更安全哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:15:04