7.9 KiB
TutorialBlock 教程流程与 Chapter 0 配置
规则
TutorialBlock 点击后通过通用 SelectionBox 动态生成“游玩教程 / 跳过教程”两个选项。玩家选择任一选项的瞬间,系统都会:
- 将 TutorialBlock 的
tutorialProgressVariable写为true。 - 保存全局剧情变量。
- 将该 TutorialBlock 标记为 Completed,用于故事树的节点外观;Completed 状态仍允许玩家再次点击回顾教程。
- 重新计算所有 StoryBlock 的条件状态(
unlockCondition与forbiddenCondition)。
后续 Block 必须通过 VariableCondition 读取教程变量解锁,不要依赖 TutorialBlock 的完成记录。选择“游玩教程”后会进入 GameScene;选择“跳过教程”则留在故事树。教程游玩中退出、失败或关闭游戏不会回退已经确认的解锁状态。教程节点完成后仍可再次点击;重复游玩只会重写相同的已处理状态,不会影响已解锁的后续剧情。
运行时职责
| 模块 | 职责 |
|---|---|
StoryProgress |
统一执行“写变量、保存、刷新故事树”;ResolveTutorial 同时更新教程节点完成状态。 |
TutorialFlowController |
验证 TutorialBlock 配置,并临时组装教程所需的两个 SelectionBoxOption。 |
MessageUIPage |
MessageBox 与 SelectionBox 共用的弹窗页面:使用同一遮罩、容器和 FIFO 队列,动态生成并依次显示弹窗。 |
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. 配置教程曲目表
- 打开
Assets/Resources/TutorialCollection.asset。 - 在
songs字典中将现有 Chapter 0 教程条目的 Key 调整为chapter0_intro。保留其对应的SongItemData,不要重新手工复制曲目数据。 - 检查该教程条目的
difficultyDataList:目标难度应为isAvailable = true,并确认它的saveDifficultyId。当前 Chapter 0 Tutorial 的 Easy 难度应使用 ID0;以 Inspector 实际显示为准。
2. 在 StoryData 新增起始教程节点
- 打开
Assets/Story/Chapter0/StoryData_Chapter0.asset。 - 在
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 |
留空,使教程节点在章节开始时可点击 |
- 为原本的第一个剧情节点
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:
- 创建一个
SelectionBoxButtonPrefab:根节点具有Button与SelectionBoxButton,子节点具有TMP_Text。将 Button 和文本分别赋给button、labelText。 - 创建一个
SelectionBoxPrefab:根节点具有CanvasGroup与SelectionBox;配置标题TMP_Text、可选内容TMP_Text、选项容器RectTransform,并把上一步 Prefab 赋给optionButtonPrefab。 - 打开
Assets/Scenes/MenuScene.unity中现有的MessagePage。该节点已有CanvasGroup与MessageUIPage,无需创建新的全屏覆盖页或在MenuManager新增引用。 - 将上一步的
SelectionBoxPrefab 赋给MessageUIPage.defaultSelectionBoxPrefab。它会与现有MessageBox共用messageContainer。
教程点击时会运行时生成一个 SelectionBox,并生成两个按钮:游玩教程 与 跳过教程。未来其它非 Yarn 的交互(例如奖励二选一、离开确认、章节分支)可以传入自己的标题、内容和 SelectionBoxOption 列表复用这套 UI。按钮正式本地化留待剧情文本与本地化阶段处理。
4. 推荐按钮排版(SelectionBox 宽度 1200)
建议所有 2~3 个选项统一使用纵向等宽排列,而不是根据数量切换横向布局。这样在英文、日文、韩文和越南文的按钮文字长度不同时,仍有稳定的触控面积和视觉节奏。
| 配置项 | 推荐值 |
|---|---|
optionContainer |
VerticalLayoutGroup |
| 左右 Padding | 72 |
| 上下 Padding | 48 |
| 按钮间距 | 24 |
| 按钮高度 | 112(通过 Button Prefab 的 LayoutElement.preferredHeight) |
| 按钮宽度 | 填满可用宽度,约 1056 |
| 对齐方式 | Middle Center |
两按钮时,选项区高度约为 248;三按钮时约为 384,均适合固定宽度 1200 的弹窗。若存在“取消 / 返回”一类非主要操作,应固定放在最后一项,并以较弱的颜色或描边区分,不要仅通过位置变化表达危险性。横向三等分在 1200 宽度下每项只有约 336 宽,对越南文和未来较长的本地化文本余量不足,因此不建议作为通用 SelectionBox 的默认布局。
验证清单
- 使用新存档或 StoryTree 的
DebugResetChapterProgress重置 Chapter 0;该调试重置现在也会清除本章节的教程变量。 - 进入 Chapter 0,确认只有 TutorialBlock 可点击,
A-0保持 Locked。 - 点击 TutorialBlock,再点击“跳过教程”:节点应变为 Completed,
A-0应立即成为 Current;重进游戏后状态应保留。 - 重置后选择“游玩教程”:确认进入 Chapter 0 Tutorial 的指定难度,且
A-0在确认按钮点击后已解锁。 - 在教程暂停页或结算页返回菜单:应回到 Chapter 0 的 StoryPage,而不是 SongSelection 页面。
- 通过普通选曲进入歌曲后返回菜单:应仍回到 SongSelection 页面,且歌曲/难度缓存不受影响。
- 在 TutorialBlock 已完成后再次点击它:应再次显示 SelectionBox,选择“游玩教程”后能够重新进入教程,且后续剧情解锁状态不变化。
配置错误的表现
以下任一配置缺失时,TutorialBlock 会输出警告且不会解锁后续剧情:tutorialKey、tutorialProgressVariable、tutorialDifficultySaveId、TutorialCollection 中的曲目、可用的目标难度、场景中的 MessageUIPage、defaultSelectionBoxPrefab 或选项按钮 Prefab。
这是一项运行时保护;本阶段不增加导入器或 Editor 阶段的额外防呆校验。