说明
若想存储某对象的数据,则该对象对应的类需继承SaveData。
SaveData提供如下方法:
保存:Save
删除:Delete
静态类SaveSys提供如下方法:
载入某项数据:Load。载入时需传入名称,要求所有要存储的对象不能重名。
存储所有数据:SaveAll
删除所有数据:DeleteAll
使用
- 可在游戏开始时Load所有继承自SaveData的数据。
- 在合适的时机SaveAll或Save特定数据。
- 在合适的时机Delete特定数据。Delete后,需自行调用Destroy方法,重新Load该数据(这次Load的本质是创建新存档)。
具体代码
SaveSys.cs
包含SaveData和SaveSys
using System;
using UnityEngine;
[Serializable]
public abstract class SaveData
{
public string Name { get; private set; }
public void Init(string name)
{
Destroy();
Name = name;
SaveSys.SaveEvent += OnSave;
SaveSys.DeleteEvent += OnDelete;
SaveSys.ShowEvent += OnShow;
}
public void Destroy()
{
SaveSys.SaveEvent -= OnSave;
SaveSys.DeleteEvent -= OnDelete;
SaveSys.ShowEvent -= OnShow;
}
private void OnSave()
{
Save();
}
private void OnDelete()
{
Delete();
}
private void OnShow()
{
Debug.Log("存档名称:" + Name);
}
public void Save()
{
SaveSys.Save(Name, this);
}
public void Delete()
{
SaveSys.Delete(Name);
}
}
public static class SaveSys
{
// 存储所有
public static event Action SaveEvent;
// 删除所有
public static event Action DeleteEvent;
// 显示名称
public static event Action ShowEvent;
private static string NameToPath(string name)
{
return Application.persistentDataPath + "/" + name + ".txt";
}
public static T Load<T>(string name) where T : SaveData, new()
{
var dataStr = string.Empty;
var path = NameToPath(name);
if (System.IO.File.Exists(path))
{
System.IO.StreamReader file = System.IO.File.OpenText(path);
dataStr = file.ReadToEnd();
file.Close();
}
T t = null;
if (dataStr != string.Empty)
{
t = JsonUtility.FromJson<T>(dataStr);
}
else
{
// t = (T)System.Activator.CreateInstance(typeof(T), name);
t = new T();
Debug.Log("载入存档数据失败。当前还不存在该存档:" + name + "。创建新存档。");
}
t.Init(name);
t.Save();
return t;
}
public static void Save<T>(string name, T t)
{
string content = JsonUtility.ToJson(t, true);
var path = NameToPath(name);
if (!System.IO.File.Exists(path))
{
// 创建后要主动释放:Dispose
System.IO.File.CreateText(path).Dispose();
}
System.IO.File.WriteAllText(path, content, System.Text.Encoding.UTF8);
Debug.Log(nameof(SaveSys) + ":保存:" + name);
}
public static void Delete(string name)
{
var path = NameToPath(name);
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
Debug.Log("删除:" + name);
}
}
public static void SaveAll()
{
SaveEvent?.Invoke();
Debug.Log(nameof(SaveSys) + ":保存了所有!");
}
public static void DeleteAll()
{
DeleteEvent?.Invoke();
Debug.Log(nameof(SaveSys) + ":删除了所有!");
}
public static void ShowAll()
{
ShowEvent?.Invoke();
Debug.Log(nameof(SaveSys) + ":如上是所有存档数据!");
}
}
PlayerData.cs
SaveData的子类,用于测试
using UnityEngine;
public class PlayerData : SaveData
{
public Vector3 Pos;
}
SaveTest.cs
用于测试
using UnityEngine;
public class SaveTest : MonoBehaviour
{
private void Start()
{
Init();
}
private void Update()
{
MyUpdate();
}
private void OnDestroy()
{
MyDestroy();
}
private void Init()
{
}
private PlayerData _playerData;
private PlayerData PlayerData
{
get
{
_playerData ??= SaveSys.Load<PlayerData>(nameof(PlayerData));
return _playerData;
}
}
private void MyUpdate()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("存档中的Player位置:" + PlayerData.Pos);
}
else if (Input.GetKeyDown(KeyCode.A))
{
SaveSys.ShowAll();
}
else if (Input.GetKeyDown(KeyCode.B))
{
SaveSys.SaveAll();
}
else if (Input.GetKeyDown(KeyCode.C))
{
SaveSys.DeleteAll();
}
else if (Input.GetKeyDown(KeyCode.D))
{
PlayerData.Pos = Vector3.one * UnityEngine.Random.Range(0, 100);
Debug.Log("修改Player位置:" + PlayerData.Pos);
PlayerData.Save();
}
}
private void MyDestroy()
{
}
}
网友评论