Files
ichni_Official/docs/story-ui-refactor-plan.md
SoulliesOfficial c30bb258b1 Story排版
2026-07-20 16:56:04 -04:00

6.3 KiB
Raw Blame History

剧情界面与路线系统重构方案

状态:已确认,待实施
更新日期2026-07-20
适用范围:ichni Official。本方案不涉及 IchniCreatorStudio

1. 目标与原则

本次重构将剧情页面升级为以叙事时间推进的可拖动画面:左侧 Helper、顶部 Timeline、中心剧情树、右下章节指示器共同呈现章节进度。

剧情路线的排版是叙事与美术设计的一部分,因此必须由每章的 StoryData 静态定义;运行时仅负责生成视图、推导状态、播放动效和筛选可见信息,绝不进行自动图布局或重排。

2. 静态布局与运行时行为

2.1 StoryData 静态定义

每章 StoryData 预先保存:

  • 全部 Block、连接关系、gridColumngridRow
  • TextBlock 的 Important / Secondary 视觉分类;
  • Block 的解锁条件与变量驱动的互斥路线条件;
  • Timeline Marker 的锚点、文本和主线进度;

全局 Helper 不属于任何章节的 StoryData。它由独立的 StoryHelperData 资产保存, 并由 StoryManager 统一引用;这样所有章节共享同一个 Helper 与对话池,后续只需在该资产中维护一次。

gridColumn 表示叙事时间,向右递增;gridRow 表示路线。主线围绕 gridRow = 0 排布分支向上或向下展开。Important TextBlock 承担主线转折与章节 checkpointSecondary TextBlock 用于补充剧情和支线,可使用小数列位置。

只有叙事真正汇合时才连接到同一个后续 Block。两个结局固定在最右侧的结局区上下分置。

2.2 运行时动态生成

StoryTreeController 根据静态蓝图动态实例化 Block、Connector 和 Timeline Marker View。路线改变时不会移动或重新排列任何节点只更新各节点状态、连接线视觉和 Timeline 可见性。

3. Block 状态与互斥路线

现有状态扩展为:

状态 含义
Locked 当前不可用,但后续仍可能解锁。
Current 当前可进入。
Completed 已完成。
Forbidden 已被互斥路线排除,在本章当前路线下不能再进入。

每个 Block 同时拥有 unlockConditionforbiddenCondition,二者均使用通用的 StoryCondition 条件树。unlockCondition 留空表示可解锁;forbiddenCondition 留空表示不会被条件禁用。运行时若 forbiddenCondition 先满足,则 Block 进入 Forbidden,优先于 Completed / Current / Locked。

路线使用普通剧情变量配置:例如 chapter0_route_main = 1 表示上方路线、= 2 表示下方路线。上方 Block 可将 unlockCondition 设为 chapter0_route_main == 1,并在 forbiddenCondition 中设为 chapter0_route_main == 2;下方 Block 使用相反配置。这样路线选择、教程、Yarn 条件与其它剧情判断完全共用同一种条件语法。

Forbidden Block 保留在剧情树中、不响应点击,并通过预留的视觉函数显示专用图片或文本。关联 Connector 可同步使用低透明度或失效视觉。Timeline 不显示 Forbidden 路线的 Marker。

4. Timeline

Timeline 表达章节内的叙事时间,而非章节列表。

每个 Marker 单独配置:

  • markerId
  • anchorBlockId:唯一的位置来源;
  • 本地化时间文本或特殊自定义文本;
  • progressValue0 至 1 的章节主线进度;
  • 可选路线条件。

运行时直接读取目标 Block 的 gridColumn 计算 Marker 横坐标。Timeline 固定在屏幕顶部,并随剧情树横向拖动同步移动;纵向拖动不影响 Timeline。

Marker 锚定的 TextBlock 为 CurrentCompleted 时显示;处于 LockedForbidden 时隐藏。章节进度只取所有已完成、有效 Marker 中最大的 progressValue;两条不同结局都设置为 1.0,支线不参与主线百分比计算。

5. Helper

Helper 使用独立的场景内 HelperTalk 面板,不使用模态 MessageUIPage

StoryHelperData 是独立的全局 ScriptableObject。每条候选对话可包含本地化文本、剧情/路线条件和权重。当前版本从所有条件满足的候选中随机抽取,并在候选数量大于一时避免连续重复;无可用候选时使用默认兜底对话。

未来可在不改变 UI 架构的前提下,按剧情变量、时间阶段、路线、角色状态等扩展筛选规则。

6. SongBlock

  • 点击 SongBlock 后进入选曲页面,并优先选中其配置的目标歌曲;
  • 仅进入选曲页面或直接返回,不完成 SongBlock
  • 玩家确认进入目标歌曲时,立刻完成该 SongBlock之后中途退出游戏不回滚
  • 改选其他歌曲进入游戏,不完成原 SongBlock
  • 返回选曲或剧情时保留来源上下文,回到剧情页面后恢复章节、焦点 Block 与剧情树视口位置。

7. Important TextBlock 与章节 checkpoint

每个 Important TextBlock 都可作为本章重开点。系统为其保存“进入该 Block 之前”的章节快照:

  • checkpointBlockId
  • 已完成 Block 集合;
  • 本章剧情变量;
  • 本章选项与路线变量。

点击已完成的 Important TextBlock 时,提供“回顾剧情 / 从此处重新开始 / 取消”。选择重开会用 checkpoint 覆盖当前章节的剧情状态、将该 Block 恢复为 Current、重建剧情树并从该 Yarn Node 开始。

重开只改变本章的剧情相关数据;不会回滚歌曲成绩、设置、永久内容解锁 Key 或其他章节的进度。

8. 章节独立性

剧情变量、选项、路线和 checkpoint 都必须按章节保存与读取。Chapter 0 的剧情选择或重开不会影响 Chapter 1。

歌曲成绩、Settings 和永久内容解锁属于全局系统,不纳入章节 checkpoint 的回滚范围。

9. 实施顺序

  1. 重构 StoryData 与章节级剧情存档的数据契约。
  2. 增加 Forbidden 状态、通用 StoryCondition 与 Block 视觉接口。
  3. 移除 Block 基类的固定尺寸覆盖,改由 Prefab/Visual Preset 决定尺寸。
  4. 实现 Timeline Marker、横向同步和主线进度计算。
  5. 实现 SongBlock 到选曲、GameScene、剧情页面的完整返回上下文。
  6. 实现 Helper 对话池。
  7. 实现 Important TextBlock checkpoint 与章节重开流程。
  8. 配置 Chapter 0 的真实布局、时间点和两条结局。
  9. 完成 PC、Android、iOS 的路线、重开、拖动、Safe Area 和存档回归测试。