我發現在Unity3D遊戲引擎中保存遊戲數據的最佳方式。
起初,我使用BinaryFormatter
序列化對象。什麼是保存遊戲狀態的最佳方式?
但我聽說這種方式有一些問題,不適合保存。
那麼,什麼是最好的或推薦的方式來保存遊戲狀態?
在我的情況下,保存格式必須是字節數組。
我發現在Unity3D遊戲引擎中保存遊戲數據的最佳方式。
起初,我使用BinaryFormatter
序列化對象。什麼是保存遊戲狀態的最佳方式?
但我聽說這種方式有一些問題,不適合保存。
那麼,什麼是最好的或推薦的方式來保存遊戲狀態?
在我的情況下,保存格式必須是字節數組。
但我聽說這種方式有一些問題,不適合保存。
沒錯。在某些設備上,存在BinaryFormatter
的問題。更新或更改課程時會變得更糟。由於類不再匹配,您的舊設置可能會丟失。有時,您在閱讀保存的數據時會遇到異常。
此外,在iOS上,您必須添加Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
,否則您將遇到BinaryFormatter
問題。
保存的最佳方法是使用PlayerPrefs
和Json
。你可以學習如何做到這一點here。
在我的情況下,保存格式必須是字節數組
在這種情況下,你可以將其轉換成JSON然後轉換成JSON string
到byte
陣列。然後您可以使用File.WriteAllBytes
和File.ReadAllBytes
來保存和讀取字節數組。
這是一個可用於保存數據的通用類。幾乎與this相同,但是確實使用而不是使用PlayerPrefs
。它使用文件來保存json數據。
DataSaver
類:
public class DataSaver
{
//Save Data
public static void saveData<T>(T dataToSave, string dataFileName)
{
string tempPath = Path.Combine(Application.persistentDataPath, "data");
tempPath = Path.Combine(tempPath, dataFileName + ".txt");
//Convert To Json then to bytes
string jsonData = JsonUtility.ToJson(dataToSave, true);
byte[] jsonByte = Encoding.ASCII.GetBytes(jsonData);
//Create Directory if it does not exist
if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(tempPath));
}
//Debug.Log(path);
try
{
File.WriteAllBytes(tempPath, jsonByte);
Debug.Log("Saved Data to: " + tempPath.Replace("/", "\\"));
}
catch (Exception e)
{
Debug.LogWarning("Failed To PlayerInfo Data to: " + tempPath.Replace("/", "\\"));
Debug.LogWarning("Error: " + e.Message);
}
}
//Load Data
public static T loadData<T>(string dataFileName)
{
string tempPath = Path.Combine(Application.persistentDataPath, "data");
tempPath = Path.Combine(tempPath, dataFileName + ".txt");
//Exit if Directory or File does not exist
if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
{
Debug.LogWarning("Directory does not exist");
return default(T);
}
if (!File.Exists(tempPath))
{
Debug.Log("File does not exist");
return default(T);
}
//Load saved Json
byte[] jsonByte = null;
try
{
jsonByte = File.ReadAllBytes(tempPath);
Debug.Log("Loaded Data from: " + tempPath.Replace("/", "\\"));
}
catch (Exception e)
{
Debug.LogWarning("Failed To Load Data from: " + tempPath.Replace("/", "\\"));
Debug.LogWarning("Error: " + e.Message);
}
//Convert to json string
string jsonData = Encoding.ASCII.GetString(jsonByte);
//Convert to Object
object resultValue = JsonUtility.FromJson<T>(jsonData);
return (T)Convert.ChangeType(resultValue, typeof(T));
}
public static bool deleteData(string dataFileName)
{
bool success = false;
//Load Data
string tempPath = Path.Combine(Application.persistentDataPath, "data");
tempPath = Path.Combine(tempPath, dataFileName + ".txt");
//Exit if Directory or File does not exist
if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
{
Debug.LogWarning("Directory does not exist");
return false;
}
if (!File.Exists(tempPath))
{
Debug.Log("File does not exist");
return false;
}
try
{
File.Delete(tempPath);
Debug.Log("Data deleted from: " + tempPath.Replace("/", "\\"));
success = true;
}
catch (Exception e)
{
Debug.LogWarning("Failed To Delete Data: " + e.Message);
}
return success;
}
}
USAGE:
實施例類保存:
[Serializable]
public class PlayerInfo
{
public List<int> ID = new List<int>();
public List<int> Amounts = new List<int>();
public int life = 0;
public float highScore = 0;
}
保存數據:
PlayerInfo saveData = new PlayerInfo();
saveData.life = 99;
saveData.highScore = 40;
//Save data from PlayerInfo to a file named players
DataSaver.saveData(saveData, "players");
加載數據:
PlayerInfo loadedData = DataSaver.loadData<PlayerInfo>("players");
if (loadedData == null)
{
return;
}
//Display loaded Data
Debug.Log("Life: " + loadedData.life);
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]);
}
刪除數據:
DataSaver.deleteData("players");
謝謝! 因爲我們的項目需要mono2x設置,所以我們的環境設置失敗了。 我會嘗試JsonUtility和您的評論! – Sizzling
爲什麼一定要你的格式是一個字節數組?爲什麼不把它保存到PlayerPrefs? –
使用序列化有什麼問題? –