2016-12-05 7 views
6

Unity3Dゲームエンジンにゲームデータを保存する最良の方法が見つかりました。
最初は、BinaryFormatterを使用してオブジェクトをシリアル化します。ゲームの状態を保存する最良の方法は何ですか?

しかし、私はこの方法でいくつかの問題があり、保存には適していないと聞きました。
ゲームの状態を保存するには、どのような方法が最適ですか?

私の場合、保存形式はバイト配列でなければなりません。

+0

はなぜあなたの形式は、バイト配列でなければなりませんか?それをPlayerPrefsに保存してみませんか? –

+1

シリアル化を使用する際の問題点は何ですか? –

答えて

20

しかし、私はこの方法にはいくつかの問題があり、保存には適していないと聞きました。

そうです。一部の端末では、BinaryFormatterに問題があります。クラスを更新または変更すると悪化します。クラスが一致しないため、古い設定が失われる可能性があります。場合によっては、これにより保存されたデータを読み込む際に例外が発生することがあります。

また、iOSではEnvironment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");を追加するか、BinaryFormatterで問題が発生します。

保存する最も良い方法は、PlayerPrefsJsonです。あなたはそれを行う方法を学ぶことができますhere。私の場合は

、形式を保存するにはこの場合、バイト配列

でなければならない、あなたはJSON stringbyte配列に変換後、JSONに変換することができます。 File.WriteAllBytesFile.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"); 
+0

ありがとう! 私たちのプロジェクトはmono2x設定が必要なので、環境設定に失敗しました。 私はJsonUtilityとあなたのコメントにしようとします! – Sizzling

関連する問題