ISaveSystem
按槽位进行存档/读档操作的契约,带有事件通知。
存档失败会抛出异常。它绝不会悄无声息地返回、仿佛一切顺利 —— 这正是会让人白白损失一个下午的那种失败方式。
命名空间:OpenMon.MCE.SDK
定义
public interface ISaveSystem
{
void Save(int slot);
void Load(int slot);
bool HasSaveData(int slot);
void DeleteSave(int slot);
event Action<int> OnSaved;
event Action<int> OnLoaded;
}
engine.SaveSystem 是一个 SaveSystemFacade。Save(slot) 和 Load(slot) 只会触发它的 SaveRequested 和 LoadRequested 事件,而 OnSaved / OnLoaded 只有在引擎调用 NotifySaved / NotifyLoaded 时才会触发。在当前的引擎中,没有任何代码处理这些请求或调用这些钩子,并 且 HasSaveData(slot) / DeleteSave(slot) 操作的是 Application.persistentDataPath 中的一个 slot{N}.sav 文件,而引擎并不会写入该文件(引擎把存档保存为 Saves/ 下的具名文件夹,参见存档系统指南)。要进行真正的存档,请使用游戏内菜单,或在 Source 版和 Studio 版中使用 SavegameManager。
方法
Save(int slot)
将当前游戏状态保存到一个槽位。
| 参数 | 类型 | 描述 |
|---|---|---|
slot | int | 存档槽位索引(通常为 0-2) |
请求把所有已注册的 SavableObject 实例保存到一个 JSON 文件。实际的持久化在引擎基于协程的 SavegameManager 上运行,因此请把这次调用视为异步 —— 订阅 OnSaved 即可知道存档何时完成。
Load(int slot)
从一个槽位读取游戏状态。
| 参数 | 类型 | 描述 |
|---|---|---|
slot | int | 要读取的存档槽位索引 |
反序列化 JSON 文件,并把状态应用到所有已注册的 SavableObject 实例。如果保存的位置在另一个场景中,可能会触发场景切换。
HasSaveData(int slot)
检查某个存档槽位是否有数据。
| 参数 | 类型 | 描述 |
|---|---|---|
slot | int | 要检查的存档槽位索引 |
返回:bool -- 如果槽位包含存档数据则为 true。
DeleteSave(int slot)
删除某个槽位的存档数据。
| 参数 | 类型 | 描述 |
|---|---|---|
slot | int | 要删除的存档槽位索引 |
事件
OnSaved
在存档操作成功之后触发。
签名:event Action<int> OnSaved
| 参数 | 类型 | 描述 |
|---|---|---|
slot | int | 被保存到的槽位 |
OnLoaded
在读档操作成功之后触发。
签名:event Action<int> OnLoaded
| 参数 | 类型 | 描述 |
|---|---|---|
slot | int | 被读取的槽位 |
用法示例
using OpenMon.MCE.SDK;
using Zenject;
public class SaveLoadUI : MonoBehaviour
{
// Only IMonsterCaptureEngine is bound in DI; reach subsystems through it.
[Inject] private IMonsterCaptureEngine engine;
private ISaveSystem saveSystem;
private void Awake()
{
saveSystem = engine.SaveSystem;
}
[SerializeField] private Button[] saveButtons;
[SerializeField] private Button[] loadButtons;
[SerializeField] private Button[] deleteButtons;
[SerializeField] private Text[] slotLabels;
private void Start()
{
// Update slot labels
for (int i = 0; i < 3; i++)
{
int slot = i; // Capture for closure
slotLabels[i].text = saveSystem.HasSaveData(i)
? $"Slot {i + 1}: Saved"
: $"Slot {i + 1}: Empty";
saveButtons[i].onClick.AddListener(() => saveSystem.Save(slot));
loadButtons[i].onClick.AddListener(() =>
{
if (saveSystem.HasSaveData(slot))
saveSystem.Load(slot);
});
deleteButtons[i].onClick.AddListener(() =>
{
saveSystem.DeleteSave(slot);
slotLabels[slot].text = $"Slot {slot + 1}: Empty";
});
}
// Listen for save events
saveSystem.OnSaved += (slot) =>
{
slotLabels[slot].text = $"Slot {slot + 1}: Saved";
Debug.Log($"Game saved to slot {slot + 1}");
};
}
}