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à PlayerPrefs
và Json
. 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.WriteAllBytes
và File.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");
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? –
Sự cố khi sử dụng serialization là gì? –