我写了一个SaveLoad
类,其中包含一个Savegame
类,它包含一堆int,double,bools以及更复杂的东西,比如一组自编的类对象。< / p>
该savegame对象正在创建,序列化和AES加密保存,反之亦然 - 到目前为止,非常好。
我现在面临的问题是,如果有新的变量(在较新版本的游戏中)必须存储和加载,游戏会在加载时崩溃,因为新变量无法正确加载(因为它们不包含在旧的保存文件中)。例如。 int和double包含默认值0,而数组未初始化,因此为null。
我当前的“解决方案”:对于正在加载的每个变量,检查它是否不包含特定值(我在Savegame
类中设置)。
例如:在Savegame
我设置
public int myInt = int.MinValue;
加载时,我检查:
if(savegame.myInt != int.MinValue){
//load successful
}else{
//load failed
};
到目前为止这对于int和double来说是有效的,但是一旦我遇到第一个bool,我意识到,对于每个变量,我必须找到一个“无意义”的值(通常不可达),因此是一个失败的负载。 =&GT;粗暴的方法。
我现在可以继续将所有bools转换为int,但这很难看......
必须有一个更清洁和/或更智能的解决方案。也许是某种游戏移民?如果有一个做得好的免费插件,对我来说也没关系,但我更喜欢代码解决方案,对于遇到类似问题的其他人来说也可能更有帮助。
提前致谢! :)
答案 0 :(得分:1)
您的问题是执行不力。
如果你要进行这样的更改,你应该关注Extend,Deprecate,Delete(EDD)。
在这种情况下,您应该将新属性/字段实现为nullables,直到您可以对旧的保存文件进行数据修复。这样,您可以首先检查加载的字段是否为空或具有值。如果它有一个值,你很高兴,如果它是null,你没有值,你需要以某种方式处理。
e.g。
/*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(这将是删除步骤)
答案 1 :(得分:0)
因此,一种解决方案是将保存文件系统的版本存储在保存文件中。所以称为版本的属性。
然后在最初打开文件时,您可以调用正确的方法来加载保存游戏。它可能是一个不同的方法,一个获得版本化,不同类等的接口,但是你需要为你拥有的每个保存文件版本中的一个。
在文件版本中加载后,您可以对迁移对象/方法进行编码,这些对象/方法会在内存中成为较新版本时填充默认值。与上面的检查类似,但您需要知道需要在每个版本之间设置哪些属性/值并应用默认值。这将使您能够向前迁移到每个版本的保存文件,因此可以将真正旧的保存更新为最新版本。