Каков наилучший способ сохранить состояние игры?
Я нахожу лучший способ сохранить данные игры в Unity3D Game engine.
Сначала я сериализую объекты с помощью BinaryFormatter.
но я слышал, что этот способ имеет некоторые проблемы и не подходит для сохранения.
Итак, каков наилучший или рекомендуемый способ сохранения состояния игры?
в моем случае формат сохранения должен быть массивом байтов.
1 ответов
но я слышал, что этот способ имеет некоторые проблемы и не подходит для сохранения.
это верно. На некоторых устройствах, есть проблемы с BinaryFormatter. Это становится хуже, когда вы обновляете или меняете класс. Ваши старые настройки могут быть потеряны, так как классы больше не совпадают. Иногда вы получаете исключение при чтении сохраненных данных из-за этого.
кроме того, на iOS, вы должны добавить Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes"); или у вас будут проблемы с BinaryFormatter.
лучшие способ сохранить с PlayerPrefs и Json. Вы можете узнать, как это сделать здесь.
в моем случае формат сохранения должен быть массивом байтов
в этом случае вы можете преобразовать его в json, а затем преобразовать json string to byte массив. Затем вы можете использовать File.WriteAllBytes и File.ReadAllBytes для сохранения и чтения массива байтов.
вот общий класс, который можно использовать для сохранения данных. Почти то же самое, что этой но это не использовать 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;
}
}
использование:
пример класса для сохранения:
[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");