namespace AibisDream.SaveSystem { /// /// 从 现算的宏观摘要(场景 / 章节 SO / YarnProject)。 /// /// 替代已移除的顶层 macroStage 冗余字段:sections["scene"] / sections["macro"] 为唯一来源, /// 槽位 / 「继续游戏」等 UI 在需要展示时调用 派生,避免重复字段与读写漂移。 /// /// public readonly struct SaveSnapshotSummary { /// Addressable 场景 key,如 Scene/ClinicOut(来自 sections["scene"])。 public readonly string SceneName; /// 当前 TalkSceneSO 的 asset 名称(来自 sections["macro"])。 public readonly string SceneSoName; /// 当前 YarnProject 的 name(来自 sections["macro"],缺省回退到 anchor)。 public readonly string YarnProjectId; public SaveSnapshotSummary(string sceneName, string sceneSoName, string yarnProjectId) { SceneName = sceneName; SceneSoName = sceneSoName; YarnProjectId = yarnProjectId; } /// 从快照派生宏观摘要;兼容 sections 为强类型 DTO 或读盘后的 JObject。 public static SaveSnapshotSummary From(SaveSnapshot snapshot) { if (snapshot?.sections == null) { return new SaveSnapshotSummary(null, null, snapshot?.anchor?.yarnProjectId); } string sceneName = null; if (snapshot.sections.TryGetValue(SnapshotProviderIds.Scene, out var sceneRaw) && SnapshotSectionDeserializer.Coerce(SnapshotProviderIds.Scene, sceneRaw) is SceneSnapshotDto scene) { sceneName = scene.sceneName; } string sceneSoName = null; string yarnProjectId = null; if (snapshot.sections.TryGetValue(SnapshotProviderIds.Macro, out var macroRaw) && SnapshotSectionDeserializer.Coerce(SnapshotProviderIds.Macro, macroRaw) is MacroSnapshotDto macro) { sceneSoName = macro.sceneSoName; yarnProjectId = macro.yarnProjectId; } if (string.IsNullOrEmpty(yarnProjectId)) { yarnProjectId = snapshot.anchor?.yarnProjectId; } return new SaveSnapshotSummary(sceneName, sceneSoName, yarnProjectId); } } }