Unity3Dゲームエンジンにゲームデータを保存する最良の方法が見つかりました。
最初は、BinaryFormatter
を使用してオブジェクトをシリアル化します。ゲームの状態を保存する最良の方法は何ですか?
しかし、私はこの方法でいくつかの問題があり、保存には適していないと聞きました。
ゲームの状態を保存するには、どのような方法が最適ですか?
私の場合、保存形式はバイト配列でなければなりません。
Unity3Dゲームエンジンにゲームデータを保存する最良の方法が見つかりました。
最初は、BinaryFormatter
を使用してオブジェクトをシリアル化します。ゲームの状態を保存する最良の方法は何ですか?
しかし、私はこの方法でいくつかの問題があり、保存には適していないと聞きました。
ゲームの状態を保存するには、どのような方法が最適ですか?
私の場合、保存形式はバイト配列でなければなりません。
しかし、私はこの方法にはいくつかの問題があり、保存には適していないと聞きました。
そうです。一部の端末では、BinaryFormatter
に問題があります。クラスを更新または変更すると悪化します。クラスが一致しないため、古い設定が失われる可能性があります。場合によっては、これにより保存されたデータを読み込む際に例外が発生することがあります。
また、iOSではEnvironment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
を追加するか、BinaryFormatter
で問題が発生します。
保存する最も良い方法は、PlayerPrefs
とJson
です。あなたはそれを行う方法を学ぶことができますhere。私の場合は
、形式を保存するにはこの場合、バイト配列
でなければならない、あなたはJSON string
がbyte
配列に変換後、JSONに変換することができます。 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に保存してみませんか? –
シリアル化を使用する際の問題点は何ですか? –