在Unity中保存/加载数据

时间:2016-10-17 04:27:02

标签: c# serialization unity3d

我一直在使用Unity中的保存和加载,在其中将序列化类保存到文件中。我有一个Serializable类:

[Serializable]
class Save
{
    public List<int> ID = new List<int>();
    public List<int> Amounts = new List<int>();
}

并将其保存到文件A-OK。我可以加载它没有错误,但如果我想稍后添加:

[Serializable]
class Save
{
    public List<int> ID = new List<int>();
    public List<int> Amounts = new List<int>();
    public int extra = 0;
}

我运行我的脚本它给了我一个反序列化错误,我完全理解当我将反序列化文件转换为我的新类'已保存'时,我添加的新变量不存在并且它给了我错误。

当我在商店中修复资产时发现了这个错误,我知道一个修复可以只是更改文件名,因此创建了一个新文件,但我不想只删除之前保存的内容。

所以我的问题是,如果我想在我的序列化类中添加更多变量,如果人们要更新资产,我将如何捕获并调整旧版本的变量?

谢谢!

1 个答案:

答案 0 :(得分:18)

使用C#serializer时会出现此问题。使用JsonUtility将数据转换为Json,然后使用PlayerPrefs保存。加载时,使用PlayerPrefs加载,然后使用JsonUtility将json转换回类。

要保存的示例类:

[Serializable]
public class Save
{
    public List<int> ID = new List<int>();
    public List<int> Amounts = new List<int>();
    public int extra = 0;
    public float highScore = 0;
}

保存数据

void Save()
{
    Save saveData = new Save();
    saveData.extra = 99;
    saveData.highScore = 40;

    //Convert to Json
    string jsonData = JsonUtility.ToJson(saveData);
    //Save Json string
    PlayerPrefs.SetString("MySettings", jsonData);
    PlayerPrefs.Save();
}

加载数据

void Load()
{
    //Load saved Json
    string jsonData = PlayerPrefs.GetString("MySettings");
    //Convert to Class
    Save loadedData = JsonUtility.FromJson<Save>(jsonData);

    //Display saved data
    Debug.Log("Extra: " + loadedData.extra);
    Debug.Log("High Score: " + loadedData.highScore);

    for (int i = 0; i < loadedData.ID.Count; i++)
    {
        Debug.Log("ID: " + loadedData.ID[i]);
    }
    for (int i = 0; i < loadedData.Amounts.Count; i++)
    {
        Debug.Log("Amounts: " + loadedData.Amounts[i]);
    }
}

JsonUtility.FromJsonJsonUtility.FromJsonOverwrite之间的差异:

A JsonUtility.FromJson从Json创建新对象并返回它。它分配内存。

string jsonData = PlayerPrefs.GetString("MySettings");
//Convert to Class. FromJson creates new Save instance
Save loadedData = JsonUtility.FromJson<Save>(jsonData);

B JsonUtility.FromJsonOverwrite 创建新对象。它与为您的类添加更多数据类型无关。它只是覆盖在其中传递的数据。它有利于记忆保存和减少GC。如果您有arraystringList等字段,它将唯一分配内存。

应该使用JsonUtility.FromJsonOverwrite的示例是在使用Json执行常量数据传输时。它会提高性能。

//Create Save instance **once** in the Start or Awake function
Save loadedData = null;
void Start()
{
    //loadedData instance is created once
    loadedData = new Save();
}

void Load()
{
    string jsonData = PlayerPrefs.GetString("MySettings");
    //Convert to Class but don't create new Save Object. Re-use loadedData and overwrite old data in it
    JsonUtility.FromJsonOverwrite(jsonData, loadedData);
    Debug.Log("High Score: " + loadedData.highScore);
}