存档存储 Save
把一个可序列化对象按类型写盘、按类型读回。就这一件事。
命名空间 HYC.Framework.Save。已实现,依赖 com.unity.nuget.newtonsoft-json(已在框架 package.json 声明)。
用法
using HYC.Framework.Save;
[Serializable]
public class PlayerProgress
{
public int level;
public int coins;
public Dictionary<string, int> levelStars; // Dictionary 只有 Newtonsoft 支持
}
// 存
SaveManager.Save(new PlayerProgress { level = 3, coins = 120 });
// 取:不存在时返回 null
var p = SaveManager.Get<PlayerProgress>();
// 取:不存在时新建一个(不自动写盘,什么时候落盘仍由调用方决定)
var p2 = SaveManager.GetOrCreate<PlayerProgress>();
// 判断 / 删除
bool has = SaveManager.Has<PlayerProgress>();
SaveManager.Delete<PlayerProgress>();
SaveManager.DeleteAll();
自定义序列化器与根目录:
SaveManager.Init(new SaveOptions
{
Serializer = new JsonUtilitySaveSerializer(),
RootPath = Path.Combine(Application.temporaryCachePath, "SaveTest")
});
核心类
| 类 | 职责 |
|---|---|
SaveManager | 静态入口 |
SaveOptions | RootPath(默认 persistentDataPath/Save,可覆盖便于测试)、Serializer |
SaveEnvelope | 文件外壳,带 formatVersion / typeKey / timestamp / payload |
ISaveSerializer | 序列化抽象 |
NewtonsoftSaveSerializer | 默认实现,支持 Dictionary / 多态 / 顶层 List<T> |
JsonUtilitySaveSerializer | 零依赖备选,有三条硬限制 |
坑
Get<T>()每次都读盘,没有内存缓存。别放在每帧循环里。这是设计取舍:不缓存就没有生命周期、没有失效问题、没有Clear()。- 坏档会被改名成
.corrupt_<时间戳>,不会被覆盖。静默覆盖等于玩家进度凭空消失且无从追查。 - 类型就是键:文件名键是
typeof(T).FullName,给类改名或换命名空间 = 老存档读不到。真要改名时写一次性迁移代码,框架不做这个。 - 同一个类型只能存一份。想存多份就存
List<T>。 JsonUtilitySaveSerializer三条硬限制:不支持Dictionary、不支持多态、顶层不能直接是List<T>。用之前先确认数据不触碰这三条,否则会静默存出{}。- 自动保存时机不由框架决定:使用方需自己在
OnApplicationPause/OnApplicationFocus(false)里调Save。