123 lines
4.8 KiB
C#
123 lines
4.8 KiB
C#
using System;
|
||
using Continentis.MainGame.Saving;
|
||
using SLSUtilities.General;
|
||
using UnityEngine;
|
||
|
||
namespace Continentis.MainGame
|
||
{
|
||
/// <summary>
|
||
/// 负责游戏存档的读写、校验和删除。
|
||
/// 跨场景持久,挂载在初始场景的 SaveManager GameObject 上。
|
||
/// 内存中缓存一份 GameSave,所有操作均通过缓存进行,
|
||
/// 保证 PlayerSave(成就、统计)不会被跑局操作意外覆盖。
|
||
/// </summary>
|
||
public class SaveManager : Singleton<SaveManager>
|
||
{
|
||
private const string SaveKey = "GameSave";
|
||
private const string SaveFilePath = "save.es3";
|
||
|
||
/// <summary>内存中的存档缓存,Awake 时从文件加载,不存在则新建。</summary>
|
||
private GameSave _cache;
|
||
|
||
// ── 生命周期 ──────────────────────────────────────────────────────
|
||
|
||
protected override void Awake()
|
||
{
|
||
Initialize(dontDestroy: true);
|
||
LoadOrCreate();
|
||
}
|
||
|
||
// ── 查询 API ──────────────────────────────────────────────────────
|
||
|
||
/// <summary>返回缓存中的 PlayerSave(账号级数据)。</summary>
|
||
public PlayerSave PlayerData => _cache.playerData;
|
||
|
||
/// <summary>判断当前是否存在未完成的跑局。</summary>
|
||
public bool HasActiveRun() => _cache.HasActiveRun;
|
||
|
||
// ── 跑局存档 API ──────────────────────────────────────────────────
|
||
|
||
/// <summary>
|
||
/// 将 RunSave 写入缓存并持久化。
|
||
/// 由 MainGameManager 在开局和节点边界(战斗胜利后)调用。
|
||
/// </summary>
|
||
public void SaveRunSave(RunSave runSave)
|
||
{
|
||
_cache.currentRun = runSave;
|
||
Flush();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清除当前跑局(战斗失败 / 放弃跑局),保留 PlayerSave。
|
||
/// </summary>
|
||
public void DeleteRunSave()
|
||
{
|
||
_cache.currentRun = null;
|
||
Flush();
|
||
Debug.Log("[Save] 跑局存档已清除(PlayerSave 保留)。");
|
||
}
|
||
|
||
/// <summary>返回缓存中的 RunSave,若无进行中的跑局则返回 null。</summary>
|
||
public RunSave GetRunSave() => _cache.currentRun;
|
||
|
||
// ── 账号存档 API ──────────────────────────────────────────────────
|
||
|
||
/// <summary>
|
||
/// 更新 PlayerSave 并持久化(解锁内容、统计数据变更时调用)。
|
||
/// </summary>
|
||
public void SavePlayerData(PlayerSave playerSave)
|
||
{
|
||
_cache.playerData = playerSave;
|
||
Flush();
|
||
}
|
||
|
||
// ── 全局存档 API ──────────────────────────────────────────────────
|
||
|
||
/// <summary>
|
||
/// 清除所有存档数据,包括 PlayerSave(账号重置时调用)。
|
||
/// </summary>
|
||
public void DeleteAllData()
|
||
{
|
||
if (ES3.FileExists(SaveFilePath))
|
||
{
|
||
ES3.DeleteFile(SaveFilePath);
|
||
Debug.Log("[Save] 所有存档已删除。");
|
||
}
|
||
|
||
_cache = new GameSave();
|
||
}
|
||
|
||
// ── 内部方法 ──────────────────────────────────────────────────────
|
||
|
||
/// <summary>从文件加载 GameSave;文件不存在则新建并立即持久化。</summary>
|
||
private void LoadOrCreate()
|
||
{
|
||
if (!ES3.FileExists(SaveFilePath))
|
||
{
|
||
_cache = new GameSave();
|
||
Flush();
|
||
Debug.Log("[Save] 未找到存档文件,已新建。");
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
_cache = ES3.Load<GameSave>(SaveKey, SaveFilePath, defaultValue: null) ?? new GameSave();
|
||
Debug.Log($"[Save] 存档加载成功(版本 {_cache.saveVersion})。");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"[Save] 存档加载异常,将新建:{e.Message}");
|
||
_cache = new GameSave();
|
||
Flush();
|
||
}
|
||
}
|
||
|
||
/// <summary>将当前缓存写入文件。</summary>
|
||
private void Flush()
|
||
{
|
||
_cache.saveTime = DateTime.UtcNow;
|
||
ES3.Save<GameSave>(SaveKey, _cache, SaveFilePath);
|
||
}
|
||
}
|
||
} |