Qual é a melhor maneira de salvar o estado do jogo?

Eu acho a melhor maneira de salvar os dados do jogo no mecanismo de jogo Unity3D.
No início, eu serializo objects usando BinaryFormatter .

Mas eu ouvi este caminho tem alguns problemas e não é adequado para salvar.
Então, qual é a maneira melhor ou recomendada para salvar o estado do jogo?

No meu caso, salvar formato deve ser matriz de bytes.

Mas eu ouvi este caminho tem alguns problemas e não é adequado para salvar.

Está certo. Em alguns dispositivos, há problemas com o BinaryFormatter . Fica pior quando você atualiza ou altera a turma. Suas configurações antigas podem ser perdidas, pois as classs não são mais correspondentes. Às vezes, você recebe uma exceção ao ler os dados salvos devido a isso.

Além disso, no iOS, você precisa adicionar Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes"); ou você terá problemas com o BinaryFormatter .

A melhor maneira de economizar é com PlayerPrefs e Json . Você pode aprender como fazer isso aqui .

No meu caso, salvar formato deve ser matriz de bytes

Neste caso, você pode convertê-lo para json e depois converter a string json em array de byte . Em seguida, você pode usar File.WriteAllBytes e File.ReadAllBytes para salvar e ler a matriz de bytes.

Aqui está uma class genérica que pode ser usada para salvar dados. Quase o mesmo que isso, mas não usa PlayerPrefs . Usa o arquivo para salvar os dados do json.

Classe DataSaver :

 public class DataSaver { //Save Data public static void saveData(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(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(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; } } 

USO :

Exemplo de class para salvar :

 [Serializable] public class PlayerInfo { public List ID = new List(); public List Amounts = new List(); public int life = 0; public float highScore = 0; } 

Guardar dados:

 PlayerInfo saveData = new PlayerInfo(); saveData.life = 99; saveData.highScore = 40; //Save data from PlayerInfo to a file named players DataSaver.saveData(saveData, "players"); 

Carregar dados:

 PlayerInfo loadedData = DataSaver.loadData("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]); } 

Excluir dados:

 DataSaver.deleteData("players");