Files
Continentis/Assets/Scripts/MainGame/Saving/SaveManager.cs

123 lines
4.8 KiB
C#
Raw Normal View History

2026-04-01 12:23:27 -04:00
using System;
using Continentis.MainGame.Saving;
2026-04-17 12:01:50 -04:00
using SLSUtilities.General;
2026-04-01 12:23:27 -04:00
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);
}
}
}