2016-09-28 75 views
2

我写了一个SaveLoad类,其中包含一个Savegame类,它有一串ints,double,bools,还有一些更复杂的东西,比如自写的类对象数组。Unity/C#Savegame迁移

保存游戏对象正在创建,序列化和AES保存加密,反之亦然加载 - 迄今为止,这么好。

我现在面临的问题是,如果有新的变量(在较新版本的游戏中)必须存储和加载,游戏在加载时崩溃,因为新变量无法加载正确(因为它们不包含在旧的保存文件中)。例如。 ints和double包含默认的0,而数组未初始化,因此为null。

我目前的“解决方案”:对于每个正在加载的变量,检查它是否不包含特定的值(我在Savegame类中设置)。 例如:在Savegame我设置

public int myInt = int.MinValue; 

,当加载,我检查:

if(savegame.myInt != int.MinValue){ 
    //load successful 
}else{ 
    //load failed 
}; 

到目前为止是这种用于int和double,但一旦我打的第一布尔,我意识到,对于每个变量,我必须找到一个“没有意义”(通常不可达)的值,因此是一个失败的负载。 =>对于布尔的低劣方法。

现在我可以继续前进,将所有的bool为int,但这变丑...

必须有一个更清洁和/或更聪明地解决了这个。也许某种存储游戏迁移器?如果有一个很好的免费插件,这对我来说也可以,但我更喜欢代码解决方案,这对于其他类似问题的人可能也更有帮助。

在此先感谢! :)

+0

保存和加载数据已在此回答了很多次网站上的新问题应标记为重复。使用[JsonUtility]将数据转换为Json(http://stackoverflow.com/questions/36239705/deserialization-of-json-using-minijson-in-unity-c-sharp/36244111#36244111),使用AES对其进行加密然后用[PlayerPrefs](https://docs.unity3d.com/ScriptReference/PlayerPrefs.html)保存。加载数据时,请执行后面提到的步骤。而已。 – Programmer

+0

我已阅读了多篇文章。他们没有详细讨论如何处理旧的保存文件。这里的问题不是保存和加载本身,而是特别处理旧的保存文件以避免造成任何问题。 – Tavados

+0

首先问问自己:游戏的新版本应该能够读取过时的保存文件吗?如果是,则决定处理该问题的逻辑,然后在代码中实现该逻辑。一个例子可能是“如果某个值不存在,则将其初始化为默认状态(0,emptylist,dollars.None等)。 –

回答

0

因此,一种解决方案是将保存文件系统的版本存储在保存文件本身。所以一个名为版本的属性。

然后当最初打开文件时,您可以调用正确的方法来加载保存游戏。它可能是一种不同的方法,一个获得版本化的接口,不同的类等等,但是对于每个保存文件版本,您都需要其中的一个。

将文件加载到文件的版本中之后,可以编写迁移对象/方法来填充默认值,因为它会成为内存中的新版本。与上面的检查类似,但您需要知道每个版本之间需要设置哪些属性/值并应用默认值。这将使您可以将每个版本的保存文件转移到其他存储文件,因此可以将旧的保存更新为可用的最新版本。

+0

是的,这就是“每次更新数百个新的LoC” - 这么做肯定会起作用,但我希望能有一个更轻量级的解决方案 – Tavados

1

你的问题是执行不力。

如果您要进行这样的更改,您应该遵循扩展,弃用,删除(EDD)。

在这种情况下,您应该实现新的属性/字段作为可空,直到您可以通过数据修复旧的保存文件。这样,您可以先检查加载的字段是否为空值或具有值。如果它具有价值,那么你很好走,如果它是空的,你没有价值,你需要以某种方式处理。

例如

/*We deprecate the old one by marking it obsolete*/ 
[Obsolete("Use NewSaveGameFile instead")] 
public class OldSaveGameFile 
{ 
    public int SomeInt { get; set; } 
} 

/*We extend by creating a new class with old one's fields*/ 
/*and the new one's fields as nullables*/ 
public class NewSaveGameFile 
{ 
    public int SomeInt { get; set; } 
    public bool? SomeNullableBool { get; set; } 
} 

public class FileLoader 
{ 
    public SavedGame LoadMyFile() 
    { 
     NewSaveGameFile newFile = GetFileFromDatabase(); // Code to load the file 
     if (newFile.SomeNullableBool.HasValue) 
     { 
      // You're good to go 
     } 

     else 
     { 
      // It's missing this property, so set it to a default value and save it 
     } 
    } 
} 

然后,一旦一切都已经被数据修复时,可完全迁移到NewSaveGameFile并删除nullables(这将是删除步骤)在Unity

+0

使新变量可以为空并检查它们是否有对于原始数据类型来说,一个值似乎工作得非常好,但是如何处理一个自写类的数组呢?只需要检查整个事件是否为空? – Tavados