Unity - 向二进制格式的保存数据添加新变量?

Posted

技术标签:

【中文标题】Unity - 向二进制格式的保存数据添加新变量?【英文标题】:Unity - Adding new variables to binary formatted save data? 【发布时间】:2019-07-30 12:48:57 【问题描述】:

我使用二进制格式化程序来保存包含一堆嵌套类和参数的用户数据。当我需要向任何类添加新参数时,对于来自先前版本的用户,游戏会加载损坏的数据/根本没有数据。

我尝试在加载后对新变量进行空检查,如果它为空但不是修复,则从默认数据复制。游戏不会崩溃,但用户数据中的所有价格和等级都会丢失。

public void Load()

    GameData = new GameDataModel();

    if (File.Exists(GameFilePath + "/" + GameFileName))
    
        var bf = new BinaryFormatter();
        var file = File.Open(GameFilePath + "/" + GameFileName, FileMode.Open);
        var gameData = (GameDataModel)bf.Deserialize(file);
        file.Close();

        if (string.IsNullOrEmpty(gameData.WorldName))
        
            GameData = CreateDefaultGameData();
        
        else
        
            GameData = gameData;
        
    
    else
    
        GameData = CreateDefaultGameData();
    

    for (int i = 0; i < GameData.Cities.Count; i++)
    
        if (GameData.Cities[i].FoodStall == null)
            GameData.Cities[i].FoodStall = CreateDefaultGameData().Cities[i].FoodStall;
        if (GameData.Cities[i].Billboard == null)
            GameData.Cities[i].Billboard = CreateDefaultGameData().Cities[i].Billboard;
        if (GameData.Cities[i].Trees == null)
            GameData.Cities[i].Trees = CreateDefaultGameData().Cities[i].Trees;
        if (GameData.Cities[i].Decorations == null)
            GameData.Cities[i].Decorations = CreateDefaultGameData().Cities[i].Decorations;
        if (GameData.Cities[i].Station.StationBuildingTypeCosts == null)
            GameData.Cities[i].Station.StationBuildingTypeCosts = CreateDefaultGameData().Cities[i].Station.StationBuildingTypeCosts;
        if (GameData.Cities[i].Station.StationBuildingType == 0)
            GameData.Cities[i].Station.StationBuildingTypeCosts = CreateDefaultGameData().Cities[i].Station.StationBuildingTypeCosts;
        if (GameData.Cities[i].Station.CapacityMultiplier == 0)
            GameData.Cities[i].Station.CapacityMultiplier = 1;
        if (GameData.Cities[i].People.DensityMultiplier == 0)
            GameData.Cities[i].People.DensityMultiplier = 1;
        if (GameData.Cities[i].Bus.ProfitMultiplier == 0)
            GameData.Cities[i].Bus.ProfitMultiplier = 1;

        GameData.Cities[i].Station.Parameters = DefaultGameData.Cities[i].Station.Parameters;
        GameData.Cities[i].Bus.Parameters = DefaultGameData.Cities[i].Bus.Parameters;
        GameData.Cities[i].People.Parameters = DefaultGameData.Cities[i].People.Parameters;
    

我希望以前版本的用户保留他们的数据,并拥有新变量的默认数据。您将如何处理向现有序列化数据添加新数据?

【问题讨论】:

【参考方案1】:

使用保存格式值

通过了解您拥有的保存文件的版本,您可以轻松确定是否尝试对给定值进行解码。

如果您没有,请添加一个。否则你将不得不这样做:

public static void deserialize(ref SerializationInfo info, ref StreamingContext context) 
    SerializationInfoEnumerator infoEnum = info.GetEnumerator();
    Hashtable values = new Hashtable();
    while(infoEnum.MoveNext()) 
        SerializationEntry val = infoEnum.Current;
        values.Add(val.Name, val.Value);
    
    ...

然后使用哈希表判断给定值是否存在。

如果您使用保存版本,您可以先将其读出,然后对其进行查询以查看会发生什么:从二进制数据中读取值或将其设置为默认值。这是way, way easier。

【讨论】:

谢谢,但我的游戏已经在 AppStore 上了。您对现有方法有什么建议,如何添加新变量? 您是在实现 ISerializable 还是依赖于 BinaryFormatter 的默认实现?如果是后者,那你就完蛋了。 我使用默认实现。我尝试了很多很多东西。我带回了以前版本中的旧类类型。但是反序列化仍然失败。我想我必须放弃现有用户(也许给他们一个启动)并更改保存系统。 如果您始终、每次都更改序列化类的字段,反序列化将始终失败,除非您(以某种方式)自己管理序列化。没有办法绕过它,因为数据是在没有元数据的情况下编码的。

以上是关于Unity - 向二进制格式的保存数据添加新变量?的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D使用 FBX 格式的外部模型 ( 向 Unity 中添加 FBX 模型 | 向 Scene 场景中添加 FBX 模型 | 3D 物体渲染 | 3D 物体材质设置 )

向 Firebase 实时数据库添加新值时如何保存当前日期/时间

向 Knockout 数字数据绑定添加十进制格式

unity如何给csv文本新增行数据信息

在运行时向对象添加属性,并保存到数据库

labview如何存储变量