- game-reviewer: 删除本地审查记录,仅Issue评论 - quality-gate-review: 删除审查记录/步骤号/阶段标准 - game-dev: 删除阶段感知节,4个工作流详情拆到技能 - game-designer: 删除原型/批量生产阶段,执行案规范拆到技能 - game-pm: 去掉节号和步骤号 - 全局去掉步骤标号(①-⑧/步骤1-5/1.4.X/第一步-第四步) - 新建技能: code-implementation/deviation-report/design-execution - 原型目录扁平化: docs/design/prototype/* → docs/design/ - requirements-analysis及子文件去步骤号和阶段引用 - stage-iteration/sketch/roadmap去任务编号 - 更新所有docs/design/路径引用
21 KiB
交互系统执行案(v0.1 原型)
迭代记录
| 版本 | 日期 | 变更内容 | 作者 |
|---|---|---|---|
| v0.1.0 | 2026-06-05 | 初版执行案,覆盖四类交互的完整行为规则 | 策划 Agent |
| v0.1.1 | 2026-06-05 | 重构状态模型为层级状态,Detecting 降为 Free 检测标记,AnimLock 降为 Interacting 子阶段,新增 postAction 分叉机制 | 策划 Agent |
| v0.1.2 | 2026-06-05 | 废纸箱改为单次翻找;UI 统一为半透明底框+一句话(去掉打字机效果);叙事视角改为小孩当下视角(去掉成人回顾);对话类只显示对话内容;拾取物通用外观;跨系统交互改为物品系统 | 策划 Agent |
状态标记:📝 设计中 | 🔄 开发中 | ✅ 已同步
系统概述
交互系统让玩家通过接近并按键的方式与环境中的物体、NPC 产生互动。v0.1 原型包含四种交互类型:观察、拾取、操作、对话(简化版)。
核心设计决定(已确认)
- 交互中断行为:输入锁定 — 交互进行中,移动输入被忽略,玩家必须按 E 或 ESC 主动关闭交互后才能恢复自由移动。
- 多交互物重叠:自动最近 + 按键切换 — 默认显示最近的交互物提示,按 Tab 或鼠标滚轮切换到范围内下一个可交互物。
- 动画期间输入:全程锁定 — 任何交互动画播放期间忽略所有按键输入,动画必须自然播完才接受新输入。
- 叙事视角:小孩当下 — 玩家就是小孩,所有文本只有小孩当下的想法或客观描述,没有成人回顾式的"现在想起来"。
- 文本 UI 统一 — 观察类、对话类、翻找无结果的文本显示,统一使用屏幕中间半透明小底框 + 一句话,无打字机效果。
状态定义
系统采用层级状态模型,顶层状态 4 个,角色同一时刻只能处于其中一个顶层状态。
顶层状态
| 状态名 | 说明 |
|---|---|
| Free | 自由状态,可正常移动。内部维护检测标记,当角色在交互物触发范围内时检测标记激活,显示提示 UI |
| Interacting | 正在进行交互,所有移动输入被忽略。内部分为三个子阶段(见下文) |
| SubSystem | 子系统状态(v0.1 预留),角色进入小游戏、对话系统等子系统的状态 |
| Cutscene | 过场动画状态(v0.1 预留),播放不可跳过/可跳过的剧情演出 |
Interacting 子阶段
Interacting 状态内部分为以下子阶段,按顺序流转:
| 子阶段 | 说明 |
|---|---|
| Enter | 交互进入阶段:角色自动转向、相机推镜等过渡动画 |
| AnimLock / Active | 动画锁定或活跃阶段:AnimLock 表示动画播放中所有按键输入被忽略;Active 表示等待玩家输入(如文本显示完毕等待按 E/ESC 关闭) |
| Exit | 交互退出阶段:相机回位、UI 淡出等收尾动画 |
Free 状态的检测标记
Free 状态内部维护一个「检测标记」(isInDetectionRange),不作为独立状态,而是 Free 状态下的布尔标记:
- 检测标记 = true:角色处于一个或多个交互物的触发范围内,显示提示 UI
- 检测标记 = false:角色不在任何交互物触发范围内,无提示 UI
状态转换规则
顶层状态转换
Free ──(E 键触发交互)──→ Interacting
Interacting ──(交互结束)──→ Free [postAction: return]
Interacting ──(交互结束)──→ SubSystem [postAction: minigame / dialogue / sceneChange]
SubSystem ──(子系统退出)──→ Free
Cutscene ──(演出结束)──→ Free
v0.1 仅实现 Free ↔ Interacting 双向转换。SubSystem 和 Cutscene 在状态模型层面已定义,v0.1 不实现具体行为。
Free 状态内部的检测标记转换
检测标记 false → true:角色进入任意交互物的触发范围
检测标记 true → false:角色离开所有交互物的触发范围
检测标记的切换不改变顶层状态(始终为 Free),仅控制提示 UI 的显示/隐藏。
Interacting 子阶段转换
Enter → AnimLock/Active:进入阶段完成后,根据交互类型进入动画锁定或活跃阶段
AnimLock → Active:动画自然播完,进入等待玩家输入阶段(如适用)
AnimLock → Exit:动画自然播完且无需玩家输入(如拾取类),直接进入退出阶段
Active → Exit:玩家按下 E/ESC 触发关闭
Exit → Free/SubSystem:退出阶段完成后,根据 postAction 回到 Free 或进入 SubSystem
交互结束后的 postAction 分叉
交互结束后根据 postAction 参数决定去向:
| postAction | 目标 | 说明 |
|---|---|---|
| return | Free | 交互结束后直接回到自由状态 |
| minigame | SubSystem | 交互结束后进入小游戏(v0.1 预留) |
| dialogue | SubSystem | 交互结束后进入对话系统(v0.1 预留) |
| sceneChange | SubSystem | 交互结束后触发场景切换(v0.1 预留) |
v0.1 所有交互的 postAction 均为 return。
行为规则
通用规则(所有交互类型共用)
触发条件
- 角色与交互物的距离 ≤ 触发半径(建议值:1.5m,可调,范围 1.0-3.0m)
- 角色当前处于 Free 状态
- 交互物未被消耗(oneShot 且已触发过的交互物不再响应)
提示 UI 显示规则
进入范围时:
- 角色进入交互物触发范围 → 该交互物上方浮现提示 UI,淡入时长 0.2 秒(建议值,可调,范围 0.1-0.5 秒)
- 提示格式:
[E] 动作词 物体名(例:[E] 查看旧冰箱) - 提示位置:物体上方的屏幕空间投影
多个交互物在范围内时:
- 仅显示当前选中交互物的提示 UI,其余交互物不显示提示
- 默认选中距离角色最近的交互物
- 距离判定点:角色脚底中心到交互物注册点的水平距离
- 玩家按 Tab 键或鼠标滚轮向下 → 切换到范围内下一个可交互物(按距离从近到远排序,循环切换)
- 玩家按鼠标滚轮向上 → 切换到范围内上一个可交互物(反向循环)
- 切换时提示 UI 立即更新为新选中物体的信息,无过渡动画
离开范围时:
- 角色离开某交互物的触发范围 → 若该交互物为当前选中物体,切换为范围内下一个最近的交互物;若范围内无其他交互物,提示 UI 淡出(0.2 秒,可调)
- 若离开的非当前选中物体,提示 UI 不变
交互触发规则
- 玩家在 Free 状态下(检测标记为 true 时)按 E 键 → 触发当前选中交互物的交互
- 触发后系统进入 Interacting 状态
- Interacting 状态下:
- 移动输入(WASD、方向键)被忽略,角色不移动
- Tab 键、鼠标滚轮被忽略,不切换交互物
- E 键和 ESC 键的行为取决于具体交互类型(见下文)
交互结束规则
- 交互结束后系统回到 Free 状态(v0.1 所有交互的 postAction 均为 return)
- 若角色仍在某交互物的触发范围内,回到 Free 状态的同时检测标记激活,立即显示提示 UI
- 若角色已不在任何交互物触发范围内(仅因 oneShot 交互物被消耗导致),回到 Free 状态且检测标记为 false
通用文本显示 UI
观察类、对话类、翻找无结果的文本显示,统一使用以下 UI 格式:
- 位置:屏幕正中偏下(距屏幕中心向下偏移约 10%屏幕高度,建议值,可调,范围 5%-20%)
- 底框:半透明黑色背景(透明度 60%,可调,范围 40%-80%),圆角矩形,宽度按文字内容自适应(左右各留边距 20 像素,建议值,可调),高度按文字行数自适应
- 文字:白色,正常字体大小,居中对齐
- 显示方式:整句一次性显示,无打字机效果
- 淡入:0.2 秒(建议值,可调,范围 0.1-0.3 秒)
- 淡出:0.2 秒(建议值,可调,范围 0.1-0.3 秒)
交互类型一:观察(Examine)
用途:查看物品或场景,触发小孩当下的想法。
触发条件
- 通用触发条件满足
- 交互物类型为 examine
触发后行为(按时间顺序)
| 阶段 | 时间 | 行为 |
|---|---|---|
| 1. 转向 | 0 秒 | 角色自动转向交互物(面朝交互物方向),转向时长 0.2 秒(建议值,可调,范围 0.1-0.4 秒) |
| 2. 推镜 | 0 秒(与转向同时开始) | 相机从当前第三人称位置平滑推向交互物前方约 0.8-1.0m(建议值,可调,范围 0.5-2.0m),高度略低于交互物中心(微仰视),推镜时长 0.5 秒(建议值,可调,范围 0.3-1.0 秒),ease-out 缓动 |
| 3. 等待 | 推镜结束后 0.2 秒 | 无动作,间隔等待 |
| 4. 文本显示 | 等待结束后 | 屏幕中间半透明底框显示一句话(小孩当下的想法),使用通用文本显示 UI,进入 Active 子阶段 |
| 5. 用户控制 | 文本显示完毕后 | 玩家可按 E 或 ESC 关闭 |
关闭行为
- 玩家按 E 或 ESC → 底框淡出(0.2 秒)→ 相机从推镜位置回到默认第三人称位置(0.3 秒,可调,范围 0.2-0.5 秒,ease-in 缓动)→ 进入 Exit 子阶段 → 回到 Free 状态
可重复交互
- oneShot 为 false 的观察类交互物可反复交互
- 每次触发的文本从该交互物的文本列表中随机选取(不重复上一次的内容;若文本列表只有一条则每次显示同一条)
交互类型二:拾取(Pick Up)
用途:收集场景中散落的小物品。
触发条件
- 通用触发条件满足
- 交互物类型为 pickup
- 该交互物未被拾取(oneShot 且已触发过则不再响应)
拾取物外观
- v0.1 白盒阶段所有拾取物使用同一通用模型(建议:简单球形或方块,尺寸约 0.1m 直径/边长)
- 通过颜色区分稀有度:普通=白色,稀有=金色
- 不需要为每个拾取物制作独立模型
触发后行为(按时间顺序)
| 阶段 | 时间点 | 行为 |
|---|---|---|
| 1. 转向 | 0 秒 | 角色自动转向交互物方向,转向时长 0.2 秒(建议值,可调,范围 0.1-0.4 秒) |
| 2. 动画 | 转向完成后 | 角色播放弯腰拾取动画(总时长约 1.0 秒,建议值,可调,范围 0.8-1.5 秒),进入 Interacting 的 AnimLock 子阶段 |
| 3. 物品消失 | 动画播放至"手触碰物品"时间点(约为动画总时长的 60% 位置,可调,范围 50%-70%) | 交互物从场景中消失 |
| 4. 通知物品系统 | 物品消失同时 | 交互系统通知物品系统「<物品名称>(品类:杂物,编号:XXX)已被拾取」。后续的拾取通知("找到了 XXX")和收集通知由物品系统和收集系统分别处理 |
| 5. 自动结束 | 动画自然播完 | 系统回到 Free 状态 |
关闭行为
- 拾取交互不支持手动关闭,必须等待动画自然播完
- 动画期间所有按键输入被忽略(Interacting 的 AnimLock 子阶段)
相机行为
- 拾取全程相机保持当前第三人称位置,不推镜、不移动
一次性消耗
- 拾取类交互物均为 oneShot,拾取后永久消失
- 消失后该交互物的触发范围不再生效
交互类型三:操作(Operate)
用途:与场景设施或大型物体交互。
v0.1 包含两种操作子类型,行为规则分别定义。
子类型 3A:门(开/关切换)
触发条件
- 通用触发条件满足
- 交互物类型为 operate,子类型为 door
触发后行为(按时间顺序)
| 阶段 | 时间点 | 行为 |
|---|---|---|
| 1. 转向 | 0 秒 | 角色自动转向门的方向,转向时长 0.2 秒(建议值,可调,范围 0.1-0.4 秒) |
| 2. 动画 | 转向完成后 | 角色播放伸手推/拉门动画(总时长约 0.8 秒,可调,范围 0.5-1.2 秒),进入 Interacting 的 AnimLock 子阶段 |
| 3. 状态切换 | 动画播放至"手触碰门"时间点(约为动画总时长的 40% 位置,可调) | 门的状态切换(关→开,或开→关),门的视觉表现立即更新 |
| 4. 自动结束 | 动画自然播完 | 系统回到 Free 状态 |
相机行为
- 门操作全程相机保持当前第三人称位置,不推镜
可重复交互
- 门可反复操作,每次切换开关状态
- 提示文字根据当前状态变化:门为关闭状态时显示
[E] 打开门,门为打开状态时显示[E] 关上门
子类型 3B:废纸箱(翻找)
触发条件
- 通用触发条件满足
- 交互物类型为 operate,子类型为 search
触发后行为(按时间顺序)
| 阶段 | 时间点 | 行为 |
|---|---|---|
| 1. 转向 | 0 秒 | 角色自动转向纸箱方向,转向时长 0.2 秒(建议值,可调) |
| 2. 推镜 | 0 秒(与转向同时) | 相机推向纸箱前方约 0.6m(建议值,可调,范围 0.4-1.0m),推镜时长 0.5 秒(可调,范围 0.3-1.0 秒),ease-out 缓动 |
| 3. 动画 | 转向完成后 | 角色播放弯腰翻找动画(总时长约 1.5 秒,可调,范围 1.0-2.0 秒),进入 Interacting 的 AnimLock 子阶段 |
| 4. 结果判定 | 动画自然播完后 | 根据纸箱是否有物品,走不同分支(见下文) |
有物品分支
- 纸箱内有物品时(v0.1 的废纸箱必定包含「水浒卡(武松)」):
- 交互系统通知物品系统「<物品名称>(品类:杂物,编号:XXX)已获得」
- 物品系统弹出拾取通知「找到了 水浒卡(武松)」,收集系统弹出收集通知
- 无文本底框显示
- 玩家按 E 或 ESC → 相机回位(0.3 秒)→ 回到 Free 状态
无物品分支
- 纸箱内无物品时(v0.1 废纸箱必定有物品,此分支为架构预留):
- 屏幕中间显示通用文本底框:
什么都没找到。 - 玩家按 E 或 ESC → 底框淡出 → 相机回位 → 回到 Free 状态
一次性交互
- 废纸箱为 oneShot 交互物:翻找一次后不可再翻找
- 翻找后纸箱不消失(视觉仍在场景中),但不再显示交互提示
交互类型四:对话(Talk)— v0.1 简化版
用途:与场景中的 NPC 交谈。v0.1 为简化实现,只显示 NPC 的对话或状态表现。
触发条件
- 通用触发条件满足
- 交互物类型为 talk
触发后行为
| 阶段 | 时间 | 行为 |
|---|---|---|
| 1. 转向 | 0 秒 | 角色自动转向 NPC 方向,转向时长 0.2 秒(建议值,可调) |
| 2. 推镜 | 0 秒(与转向同时) | 相机推向 NPC 前方约 0.8-1.0m(建议值,可调),推镜时长 0.5 秒(可调) |
| 3. 文本显示 | 推镜结束后 0.2 秒 | 屏幕中间半透明底框显示 NPC 的对话内容(仅对话文本,无旁白描述),使用通用文本显示 UI |
| 4. 用户控制 | 文本显示后 | 玩家按 E 或 ESC 关闭 |
关闭行为
- 按 E 或 ESC → 底框淡出 → 相机回位 → 回到 Free 状态
可重复交互
- NPC 可反复交谈
- 每次触发的对话文本从该 NPC 的文本列表中随机选取(不重复上一次;列表只有一条则每次相同)
边界情况处理
快速连续按键
- 任何交互触发后,在 Interacting 的 AnimLock 子阶段所有按键输入被忽略
- 交互结束回到 Free 状态后才能再次按 E 触发新交互
- 不存在"连续按 E 触发多次交互"的可能
交互物被消耗后范围残留
- oneShot 交互物被消耗后,其触发范围立即失效
- 若消耗后角色附近无其他交互物,系统回到 Free 状态,检测标记置为 false
- 若消耗后角色附近仍有其他交互物,系统保持在 Free 状态,检测标记保持为 true,自动选中最近的可用交互物
推镜期间角色位置
- 推镜期间移动输入被忽略,角色不移动
- 推镜完成后角色仍在原位置,相机回到默认第三人称位置时以角色当前位置为基准
角色在交互进行中被强制位移(外部因素)
- v0.1 无物理碰撞推力系统,不存在此情况
- 若后续版本加入外部位移力(如爆炸、传送),需要额外定义中断规则,v0.1 不处理
同一交互物反复进出范围
- 角色反复进出某交互物的触发范围 → 提示 UI 每次进入时淡入、离开时淡出,无累积副作用
- 不产生"多次进入导致提示叠加"的问题,因为提示 UI 始终只显示当前选中物体的一条
切换交互物时按 E
- 按 Tab 或滚轮切换选中物体的瞬间,如果玩家恰好同时按 E → 以切换完成后的新选中物体为准
- 即:先完成切换,再判定 E 键按下时的选中物体
交互物距离恰好等于触发半径
- 距离 ≤ 触发半径 → 在范围内
- 距离 > 触发半径 → 不在范围内
- 恰好在边界上视为在范围内
跨系统交互
与角色控制系统的关系
- 交互进行中(Interacting 状态及其子阶段),角色控制系统接收"交互中"信号,忽略所有移动输入
- 交互结束后,角色控制系统恢复正常输入响应
- 角色面朝方向的自动转向由交互系统控制,不由角色控制系统控制
与物品系统的关系
- 拾取类交互触发后,交互系统在拾取动画执行到「物品消失」时间点时,通知物品系统「<物品名称>(品类:杂物,编号:XXX)已被拾取」
- 废纸箱翻找获得物品时,同样通知物品系统
- 物品系统负责:物品进入背包、弹出拾取通知("找到了 XXX")
- 收集系统从物品系统接收通知,弹出收集通知("发现了新的杂物,进度 X/Y")
- 交互系统不直接与收集系统通信
与 UI 系统的关系
- 交互提示 UI(
[E] 查看旧冰箱)由交互系统控制显示/隐藏/切换 - 文本底框(观察想法、对话内容、翻找无结果)由交互系统控制显示/关闭
- 拾取通知("找到了 XXX")由物品系统控制,不在交互系统执行案范围内
- 收集通知("发现了新的杂物")由收集系统控制,不在交互系统执行案范围内
v0.1 交互物清单(按实现阶段)
第一轮:系统验证(5 个)
覆盖全部 4 种交互类型,验证核心流程。
| # | 物体名 | 交互类型 | 区域 | 验证目标 |
|---|---|---|---|---|
| 1 | 旧冰箱 | 观察 | 家 | 室内大件观察,推镜 + 小孩想法 |
| 2 | 家的门 | 操作(门) | 家 | 门开关状态切换 |
| 3 | 拾取物(通用) | 拾取 | 空地 | 拾取完整流程,通知物品系统 |
| 4 | 公用电话亭 | 观察 | 街道 | 室外独立物体观察 |
| 5 | 小卖部老板 | 对话(简化) | 小卖部 | NPC 交互 |
探索路线:家(冰箱 → 门)→ 街道(电话亭)→ 小卖部(老板)→ 空地(拾取物)
第二轮:体验填充(5 个)
验证多交互物并存、不同物体形态的差异。
| # | 物体名 | 交互类型 | 区域 | 补什么体验 |
|---|---|---|---|---|
| 6 | 老式电视 | 观察 | 家 | 同区域第二件观察物 |
| 7 | 零食货架 | 观察 | 小卖部 | 矮物体推镜角度 |
| 8 | 拾取物(通用) | 拾取 | 空地 | 第二个拾取品 |
| 9 | 墙上的涂鸦 | 观察 | 街道 | 墙面类物体 |
| 10 | 废纸箱 | 操作(翻找) | 巷子 | 第二种操作类型 |
可调参数汇总
| 参数 | 建议值 | 可调范围 | 说明 |
|---|---|---|---|
| 触发半径 | 1.5m | 1.0-3.0m | 每个交互物可独立设置 |
| 提示 UI 淡入时长 | 0.2 秒 | 0.1-0.5 秒 | |
| 提示 UI 淡出时长 | 0.2 秒 | 0.1-0.5 秒 | |
| 角色转向时长 | 0.2 秒 | 0.1-0.4 秒 | |
| 推镜距离(观察类) | 0.8-1.0m | 0.5-2.0m | 根据交互物体型调整 |
| 推镜距离(翻找类) | 0.6m | 0.4-1.0m | |
| 推镜距离(对话类) | 0.8-1.0m | 0.5-2.0m | |
| 推镜时长 | 0.5 秒 | 0.3-1.0 秒 | |
| 推镜后等待 | 0.2 秒 | 0.1-0.5 秒 | 推镜结束到文本开始显示的间隔 |
| 相机回位时长 | 0.3 秒 | 0.2-0.5 秒 | |
| 文本底框背景透明度 | 60% | 40%-80% | |
| 文本底框淡入时长 | 0.2 秒 | 0.1-0.3 秒 | |
| 文本底框淡出时长 | 0.2 秒 | 0.1-0.3 秒 | |
| 拾取动画总时长 | 1.0 秒 | 0.8-1.5 秒 | |
| 物品消失时间点(动画进度) | 60% | 50%-70% | 动画播放到此比例时物品消失 |
| 门操作动画时长 | 0.8 秒 | 0.5-1.2 秒 | |
| 门状态切换时间点(动画进度) | 40% | 30%-50% | |
| 翻找动画时长 | 1.5 秒 | 1.0-2.0 秒 |
文本示例
所有文本均为小孩当下的想法或客观描述,没有成人回顾视角。
观察类
旧冰箱:
冰箱嗡嗡响。里面有冰棒,还有一瓶健力宝!
公用电话亭:
玻璃上全是小广告。投币口好像卡住了。
老式电视:
拍两下就有画面了。今天信号不太好。
零食货架:
五毛钱的辣条!还有干脆面和泡泡糖。
墙上的涂鸦:
谁画的奥特曼?画得还挺像的。
对话类(简化)
小卖部老板:
zzz
翻找结果
废纸箱(v0.1 必定获得物品,走物品系统通知,不显示文本底框)。 无物品时预留文本:
什么都没找到。