2016-12-05 15 views
6

Tôi tìm cách tốt nhất để lưu dữ liệu trò chơi trong công cụ Trò chơi Unity3D.
Lúc đầu, tôi sắp xếp các đối tượng bằng cách sử dụng BinaryFormatter.Cách tốt nhất để lưu trạng thái trò chơi là gì?

Nhưng tôi nghe theo cách này có một số vấn đề và không phù hợp để lưu.
Vì vậy, cách tốt nhất hoặc được đề xuất để lưu trạng thái trò chơi là gì?

Trong trường hợp của tôi, lưu định dạng phải là mảng byte.

+0

Tại sao định dạng của bạn phải là một mảng byte? Tại sao không lưu nó vào PlayerPrefs? –

+1

Sự cố khi sử dụng serialization là gì? –

Trả lời

20

Nhưng tôi nghe theo cách này có một số vấn đề và không phù hợp để lưu.

Đúng vậy. Trên một số thiết bị, có vấn đề với BinaryFormatter. Nó trở nên tồi tệ hơn khi bạn cập nhật hoặc thay đổi lớp học. Cài đặt cũ của bạn có thể bị mất do các lớp không còn khớp nữa. Đôi khi, bạn nhận được một ngoại lệ khi đọc dữ liệu đã lưu do điều này.

Ngoài ra, trên iOS, bạn phải thêm Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes"); hoặc bạn sẽ gặp sự cố với BinaryFormatter.

Cách tốt nhất để lưu là PlayerPrefsJson. Bạn có thể tìm hiểu cách thực hiện điều đó here.

Trong trường hợp của tôi, lưu định dạng phải là mảng byte

Trong trường hợp này, bạn có thể chuyển nó sang JSON sau đó chuyển đổi json string-byte mảng. Sau đó, bạn có thể sử dụng File.WriteAllBytesFile.ReadAllBytes để lưu và đọc mảng byte.

Đây là lớp Chung có thể được sử dụng để lưu dữ liệu. Hầu như giống như this nhưng nó không không sử dụng PlayerPrefs. Nó sử dụng tập tin để lưu dữ liệu json.

DataSaver lớp:

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; 
    } 
} 

SỬ DỤNG:

Ví dụ lớp để tiết kiệm:

[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; 
} 

Lưu dữ liệu:

PlayerInfo saveData = new PlayerInfo(); 
saveData.life = 99; 
saveData.highScore = 40; 

//Save data from PlayerInfo to a file named players 
DataSaver.saveData(saveData, "players"); 

Load dữ liệu:

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]); 
} 

Xóa dữ liệu:

DataSaver.deleteData("players"); 
+0

Cảm ơn! Vì dự án của chúng tôi yêu cầu cài đặt mono2x, Chúng tôi đã thất bại trong cài đặt Môi trường đó. Tôi sẽ cố gắng JsonUtility và bình luận của bạn! – Sizzling

Các vấn đề liên quan