Files
aibis-dream/Assets/Scripts/SaveSystem/SaveSnapshot.cs
T

202 lines
6.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
namespace AibisDream.SaveSystem
{
/// <summary>
/// 当前快照 schema 的版本号。结构变更时递增。
/// </summary>
public static class SaveSnapshotSchema
{
public const int CurrentVersion = 1;
}
/// <summary>
/// 存档快照根对象:描述「进入可存节点那一刻」的完整游戏状态。
/// <para>
/// 与槽位/文件路径解耦;序列化后写入 JSON。对应需求§3 四分类:
/// anchor(恢复锚点)、sections(宏观 scene/macro + 表现类)、yarnVariables、deepRepair(深度维修,P5)。
/// </para>
/// <para>
/// 宏观阶段(场景 / 章节 SO / YarnProject)不单独冗余存储,统一以 sections["scene"] / sections["macro"]
/// 为唯一来源;槽位 UI 等需要摘要时通过 <see cref="SaveSnapshotSummary"/> 现算派生,避免重复字段漂移。
/// </para>
/// </summary>
[Serializable]
public class SaveSnapshot
{
/// <summary>快照结构版本,对应 <see cref="SaveSnapshotSchema.CurrentVersion"/>。</summary>
public int schemaVersion = SaveSnapshotSchema.CurrentVersion;
/// <summary>保存时的 <c>Application.version</c>。</summary>
public string gameVersion;
/// <summary>保存时间(本地),格式 <c>yyyy-MM-dd HH:mm:ss</c>。</summary>
public string savedAt;
/// <summary>当前场景(恢复的第一步)。</summary>
public SceneSnapshotDto scene = new();
/// <summary>恢复锚点:章节、YarnProject 与节点,读档最后阶段重新进入。</summary>
public AnchorSnapshot anchor = new();
/// <summary>全部 Yarn 运行时变量(来自 <see cref="YarnVariableStorage"/>)。</summary>
public YarnVariablesSnapshot yarnVariables = new();
/// <summary>
/// 各子系统表现类快照,key 为 <see cref="SnapshotProviderIds"/> 中的稳定 id。
/// </summary>
public Dictionary<string, object> sections = new();
/// <summary>
/// 深度维修段。P1 捕获时不写入(null);P5 按模块策略填充。
/// </summary>
public DeepRepairSnapshot deepRepair;
}
/// <summary>
/// 恢复锚点:包含宏观章节信息,读档最后阶段加载对话工程并重新 <c>StartDialogue</c>。
/// </summary>
[Serializable]
public class AnchorSnapshot
{
/// <summary>当前章节 TalkSceneSO 名称,用于 <see cref="GameManager.SetSceneSoByName"/>。</summary>
public string sceneSoName;
public string yarnProjectId;
public string nodeName;
}
/// <summary>Yarn 变量三分组,与 Yarn Spinner 支持的类型一致。</summary>
[Serializable]
public class YarnVariablesSnapshot
{
public Dictionary<string, float> floats = new();
public Dictionary<string, string> strings = new();
public Dictionary<string, bool> bools = new();
}
#region Provider DTOs
/// <summary>sections["scene"]:当前加载的场景。</summary>
[Serializable]
public class SceneSnapshotDto
{
public string sceneName;
}
/// <summary>sections["env"]:环境时间/天气。</summary>
[Serializable]
public class EnvironmentSnapshotDto
{
/// <summary><see cref="TimesOfDay"/> 枚举名。</summary>
public string curTime;
/// <summary><see cref="Weather"/> 枚举名。</summary>
public string curWeather;
public bool isInitialized;
}
/// <summary>sections["actor"]:场景中所有角色的逐项状态。</summary>
[Serializable]
public class ActorSnapshotDto
{
public List<ActorEntrySnapshotDto> actors = new();
}
/// <summary>单个角色的快照条目。</summary>
[Serializable]
public class ActorEntrySnapshotDto
{
public string actorName;
public string slotName;
public string actorType;
public string stateName;
public float alpha;
public float faceParam;
}
/// <summary>sections["audio"]FMOD 音乐/SFX 终态与 AMB 状态(不记播放进度)。</summary>
[Serializable]
public class AudioSnapshotDto
{
/// <summary>key → FMOD event path。</summary>
public Dictionary<string, string> musicPaths = new();
public Dictionary<string, string> sfxPaths = new();
/// <summary><see cref="AmbState"/> 枚举名。</summary>
public string ambState;
}
/// <summary>
/// Timeline 终/初态标记(决策 D1.1:不按时间轴逐帧还原)。
/// 序列化进 JSON 时使用字符串形式存入 <see cref="TimelineEntrySnapshotDto.phase"/>。
/// </summary>
public enum TimelinePlaybackPhase
{
AtStart,
AtEnd,
Stopped
}
/// <summary>sections["timeline"]:各 PlayableDirector 的终/初态。</summary>
[Serializable]
public class TimelineSnapshotDto
{
public List<TimelineEntrySnapshotDto> entries = new();
}
[Serializable]
public class TimelineEntrySnapshotDto
{
public string directorName;
public bool isActive;
/// <summary><see cref="TimelinePlaybackPhase"/> 的字符串名。</summary>
public string phase;
/// <summary>若由 Addressables 加载 Timeline,记录 key;否则为空。</summary>
public string loadedAddressableKey;
}
/// <summary>sections["screen"]:屏幕饱和度与演出淡入淡出遮罩。</summary>
[Serializable]
public class ScreenSnapshotDto
{
/// <summary>Post-process Volume weight0=正常,1=完全褪色)。</summary>
public float saturationWeight;
/// <summary>
/// <see cref="PlayToolPanel"/> 演出遮罩终态:<c>true</c> = 黑屏盖住(<c>FadeIn</c> 完成);
/// <c>false</c> = 画面可见(<c>FadeOut</c> 完成或遮罩未启用)。不记录转场中间 alpha。
/// </summary>
public bool isFadeScreenCovered;
}
/// <summary>sections["fix"]Fix 场景宏观状态(FixStateMachine)。</summary>
[Serializable]
public class FixSnapshotDto
{
/// <summary><see cref="FixState"/> 枚举名。</summary>
public string state;
/// <summary>状态参数(如 BodyModule 的 ModuleState 字符串)。</summary>
public string args;
/// <summary>BodyModule 当前分组(Body/Head)。</summary>
public string moduleState;
/// <summary>EyeSystem 当前颜色阶段。</summary>
public string eyeColorState;
/// <summary>FixPanelSystem 是否已启动。</summary>
public bool isSystemOn;
/// <summary>RepairSystemManager 当前激活的系统类型名。</summary>
public string currentRepairSystemType;
}
#endregion
}