Saving/loading data in Unity
Solution 1:
This problem is known when using C# serializer. Convert the data to Json with JsonUtility
then save it with the PlayerPrefs
. When loading, load with the PlayerPrefs
then convert the json back to class with JsonUtility
.
Example class to Save:
[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;
}
Save Data:
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();
}
Load Data:
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]);
}
}
Difference between JsonUtility.FromJson
and JsonUtility.FromJsonOverwrite
:
A.JsonUtility.FromJson
creates new Object from Json and returns it. It allocates memory.
string jsonData = PlayerPrefs.GetString("MySettings");
//Convert to Class. FromJson creates new Save instance
Save loadedData = JsonUtility.FromJson<Save>(jsonData);
B.JsonUtility.FromJsonOverwrite
does not create new Object. It has nothing to do with adding more datatype to your class. It just overwrite the data that is passed in it. It's good for memory conservation and less GC. The only time it will allocate memory if when you have fields such as array
, string
and List
.
Example of where JsonUtility.FromJsonOverwrite
should be used is when performing constant data transfer with Json. It will improve performance.
//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);
}