2016-09-28 61 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