Files
ichni_Official/docs/tutorial-block-system.md

6.6 KiB
Raw Blame History

TutorialBlock 教程流程与 Chapter 0 配置

规则

TutorialBlock 点击后通过通用 SelectionBox 动态生成“游玩教程 / 跳过教程”两个选项。玩家选择任一选项的瞬间,系统都会:

  1. 将 TutorialBlock 的 tutorialProgressVariable 写为 true
  2. 保存全局剧情变量。
  3. 将该 TutorialBlock 标记为 Completed用于故事树的节点外观和防止重复点击。
  4. 重新计算所有 StoryBlock 的 UnlockCondition

后续 Block 必须通过 VariableCondition 读取教程变量解锁,不要依赖 TutorialBlock 的完成记录。选择“游玩教程”后会进入 GameScene选择“跳过教程”则留在故事树。教程游玩中退出、失败或关闭游戏不会回退已经确认的解锁状态。

运行时职责

模块 职责
StoryProgress 统一执行“写变量、保存、刷新故事树”;ResolveTutorial 同时更新教程节点完成状态。
TutorialFlowController 验证 TutorialBlock 配置,并临时组装教程所需的两个 SelectionBoxOption
SelectionBoxUIPage 通用多选弹窗页面:动态生成一个 SelectionBox,阻断底层输入并在选择后销毁该实例。
SelectionBox / SelectionBoxButton 动态生成任意数量的选项按钮并确保一次显示只执行一个回调。
TutorialCollection tutorialKey 查询教程曲目的 SongItemData
InformationTransistor MenuReturnDestination 保存唯一的返回目标,替代旧的两个返回 bool。

MenuReturnDestination.SongSelection 供普通选曲使用;MenuReturnDestination.Story 供教程使用。教程从 GameScene 返回时MenuScene 会显式重建来源章节的 StoryTree。

Key 命名规则

所有新 Tutorial Key 和剧情变量 Key 只使用小写英文、数字和下划线:

用途 Chapter 0 示例
Tutorial Key chapter0_intro
教程进度变量 story_tutorial_chapter0_intro_resolved
TutorialBlock ID建议 tutorial_0_intro

不要用显示名称、空格、点号或本地化文本作逻辑 Key。blockId 是 StoryTree 内部节点标识,旧内容可继续保留既有的 A-0 格式;新内容建议使用清晰且稳定的名称。

配置 Chapter 0

当前 Assets/Story/Chapter0/StoryData_Chapter0.asset 还没有 TutorialBlock需要在 Unity Inspector 中按以下步骤添加。

1. 配置教程曲目表

  1. 打开 Assets/Resources/TutorialCollection.asset
  2. songs 字典中将现有 Chapter 0 教程条目的 Key 调整为 chapter0_intro。保留其对应的 SongItemData,不要重新手工复制曲目数据。
  3. 检查该教程条目的 difficultyDataList:目标难度应为 isAvailable = true,并确认它的 saveDifficultyId。当前 Chapter 0 Tutorial 的 Easy 难度应使用 ID 0;以 Inspector 实际显示为准。

2. 在 StoryData 新增起始教程节点

  1. 打开 Assets/Story/Chapter0/StoryData_Chapter0.asset
  2. blocks 新增一个条目,或按你的章节布局将其放在第一个剧情节点之前:
字段 建议值
blockId tutorial_0_intro
blockType Tutorial
tutorialName 当前阶段可先填临时显示名,例如 Chapter 0 Tutorial
tutorialKey chapter0_intro
tutorialProgressVariable story_tutorial_chapter0_intro_resolved
tutorialDifficultySaveId 0(以教程曲目的实际 saveDifficultyId 为准)
nextBlockIds 第一个后续剧情节点,例如 A-0
unlockCondition 留空,使教程节点在章节开始时可点击
  1. 为原本的第一个剧情节点 A-0 设置 UnlockCondition:选择 VariableCondition,并填写:
字段
variableName story_tutorial_chapter0_intro_resolved
comparison Equal
value 1

如果该节点还有其它前置要求,请使用 AllOfCondition 将原条件与上述 VariableCondition 组合。不要把它改成 BlockCompletedCondition(tutorial_0_intro),否则会失去与 Yarn 和其它剧情变量共用条件系统的优势。

3. 配置通用 SelectionBox

TutorialBlock 不再需要专属弹窗。只需配置一套可供其它系统复用的 SelectionBox

  1. 创建一个 SelectionBoxButton Prefab根节点具有 ButtonSelectionBoxButton,子节点具有 TMP_Text。将 Button 和文本分别赋给 buttonlabelText
  2. 创建一个 SelectionBox Prefab根节点具有 CanvasGroupSelectionBox;配置标题 TMP_Text、可选内容 TMP_Text、选项容器 RectTransform,并把上一步 Prefab 赋给 optionButtonPrefab
  3. Assets/Scenes/MenuScene.unity 创建一个全屏覆盖页:根节点具有 CanvasGroupSelectionBoxUIPage,初始建议 alpha = 0interactable = falseblocksRaycasts = false
  4. 在该覆盖页下创建 selectionBoxContainer,并将它赋给 SelectionBoxUIPage.selectionBoxContainer;将上一步的 SelectionBox Prefab 赋给 selectionBoxPrefab
  5. 选中 MenuManager,把该 SelectionBoxUIPage 组件拖入新的 selectionBoxUIPage 字段。

教程点击时会运行时生成一个 SelectionBox并生成两个按钮游玩教程跳过教程。未来其它非 Yarn 的交互(例如奖励二选一、离开确认、章节分支)可以传入自己的标题、内容和 SelectionBoxOption 列表复用这套 UI。按钮正式本地化留待剧情文本与本地化阶段处理。

验证清单

  1. 使用新存档或 StoryTree 的 DebugResetChapterProgress 重置 Chapter 0该调试重置现在也会清除本章节的教程变量。
  2. 进入 Chapter 0确认只有 TutorialBlock 可点击,A-0 保持 Locked。
  3. 点击 TutorialBlock再点击“跳过教程”节点应变为 CompletedA-0 应立即成为 Current重进游戏后状态应保留。
  4. 重置后选择“游玩教程”:确认进入 Chapter 0 Tutorial 的指定难度,且 A-0 在确认按钮点击后已解锁。
  5. 在教程暂停页或结算页返回菜单:应回到 Chapter 0 的 StoryPage而不是 SongSelection 页面。
  6. 通过普通选曲进入歌曲后返回菜单:应仍回到 SongSelection 页面,且歌曲/难度缓存不受影响。

配置错误的表现

以下任一配置缺失时TutorialBlock 会输出警告且不会解锁后续剧情:tutorialKeytutorialProgressVariabletutorialDifficultySaveId、TutorialCollection 中的曲目、可用的目标难度、SelectionBoxUIPage 引用、SelectionBox Prefab 或选项按钮 Prefab。

这是一项运行时保护;本阶段不增加导入器或 Editor 阶段的额外防呆校验。