Files
ChildHood/docs/design/systems/interaction-system.md
T
2026-06-01 18:25:27 +08:00

294 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 环境交互系统 — 设计文档
> 对应程序实现:交互组件基类、交互检测、UI 提示系统
---
## 设计目标
让玩家通过"触碰"来感知这个世界——每一个可交互的物体都是一段记忆的入口。交互系统是 v0.1 的核心体验,它决定了玩家能否真正"活"在这个场景中。
---
## 交互类型
### 1. 观察(Examine) — 最核心的交互
**用途**: 查看物品或场景,触发主角的内心独白
**触发流程**: 走进触发范围(1.5m)→ 物体上方浮现提示 `[E] 查看旧冰箱` → 按 E 触发
**触发后表现**:
1. 相机从当前第三人称位置**平滑推向物体前方**约 0.8-1m,高度略低于物体中心(微仰视),推镜约 0.5 秒,ease-out 缓动
2. 角色自动转向物体(不锁定移动,可微调位置但不能跑开)
3. 相机到位后 0.2 秒,屏幕底部浮现内心独白文案(打字机效果,每字约 0.05 秒)
4. 按 E 或 ESC 关闭:文案淡出,相机 0.3 秒回到默认第三人称位置
**文案风格示例**:
```
[旧冰箱]
夏天的时候最期待打开冰箱的那一刻。
冰棒、西瓜、偶尔还有一瓶健力宝。
现在想起来,那个冰箱的嗡嗡声好像还在耳边。
[墙上的涂鸦]
不知道是谁画的,但画得还挺像奥特曼的。
我以前也想在墙上画,被我妈追着打了半条街。
[地上的弹珠]
一颗彩色花纹的弹珠,大概是哪个小孩掉的。
我以前也丢过最喜欢的那颗,找了整个下午都没找到。
```
**设计原则**:
- 每个观察文本都是一个独立的"微叙事"
- 文字简短(2-4句),不冗长
- 带有情感但不矫情
- 用孩子的视角看世界,不是大人回望
### 2. 拾取(Pick Up)
**用途**: 收集场景中散落的小物品
**触发流程**: 走近拾取品(1.5m)→ 物品上方浮现提示 `[E] 拾取 弹珠` → 按 E 触发
**触发后表现**:
1. 相机**不动**,保持第三人称视角
2. 角色播放弯腰拾取动画(约 1 秒)
3. 动画播放至"手碰到物品"时间点,物品从场景消失
4. 右上角弹出物品获得提示(图标 + 名称),1.5 秒后自动淡出
5. 收集计数 +1,自动结束(无需手动关闭)
**v0.1 可拾取物品**:
- 弹珠(不同花色)
- 小石子
- 橡皮擦
- 糖纸
- 水浒卡碎片
### 3. 操作(Operate)
**用途**: 与场景设施或大型物体交互
**触发流程**: 走近操作对象(1.5m)→ 对象上方浮现提示 `[E] 打开门` → 按 E 触发
**触发后表现**(通用模式):
1. 相机推向操作对象(同观察类型的推镜方式)
2. 角色播放对应操作动画
3. 操作完成后触发状态变化
4. 相机回到默认位置
**v0.1 操作对象及具体表现**:
| 操作对象 | 推镜 | 角色动画 | 结果 |
|----------|------|----------|------|
| 门(家/小卖部) | 不推镜 | 角色伸手推门 | 门状态切换(开↔关),开门后可走进去 |
| 废纸箱(翻找) | 推近纸箱 | 角色弯腰翻找 | 弹出翻找结果文本,或意外发现拾取品 |
**v0.1 操作交互对象**:
- 家的门(进出)
- 小卖部门(进出)
- 公用电话亭(观察 + 对话文本)
- 水塘边的石头(可以打水漂?v0.2)
### 4. 对话(Talk) — v0.1 简化版
**用途**: 与场景中的 NPC 交谈
**触发流程**: 走近 NPC(1.5m)→ NPC 上方浮现提示 `[E] 和老板说话` → 按 E 触发
**v0.1 简化方案**:
- v0.1 不实现完整对话系统
- NPC 本质上是"会说话的观察对象",交互表现与观察类型一致
- 触发后:相机推向 NPC → 底部浮现场景描述文本(非内心独白)
- 例如:走近小卖部老板 → 相机推向老板 → "老板正在柜台后面打瞌睡,电视里放着还珠格格。"
- 按 E/ESC 关闭,相机回位
- 后续版本再加入对话树和分支
---
## 交互提示 UI
### 可交互性提示(两级机制)
**远距离(3-4m 外)**:无 UI 提示,靠场景设计引导注意力
- 可交互物体的摆放位置有"意图感",不会靠墙角挤成一堆,放在玩家容易注意到的位置
- 拾取品有**微弱的地面光斑/小光点**,暗示"这里有东西"(融入夏日阳光氛围,不违和)
**近距离(1.5m 内,触发范围)**:物体上方浮现交互提示 UI
- 多个物体在范围内时,只显示最近的那个
- 角色离开触发半径时提示消失
### 提示样式
### 提示样式
```
┌─────────────────────────┐
│ [E] 查看旧冰箱 │
└─────────────────────────┘
```
- 位置:物体上方偏移(屏幕空间投影)
- 字体:简洁的中文字体,白色带轻微描边
- 图标:交互键(E)+ 动作词(查看/拾取/打开)
- 过渡:淡入淡出(0.2秒)
### 交互类型图标
| 类型 | 图标文字 | 颜色 |
|------|----------|------|
| 观察 | 🔍 查看 | 白色 |
| 拾取 | ✋ 拾取 | 黄色 |
| 操作 | 🖐 打开 | 白色 |
---
## 交互后的叙事文本 UI
### 显示位置
- 屏幕下方居中,半透明背景条
- 不遮挡主视角
### 样式
```
╭──────────────────────────────────────────╮
│ │
│ 夏天的时候最期待打开冰箱的那一刻。 │
│ 冰棒、西瓜、偶尔还有一瓶健力宝。 │
│ │
│ [E] 关闭 │
╰──────────────────────────────────────────╯
```
- 背景:半透明黑色(透明度约60%)
- 文字:白色,逐字出现(打字机效果,每字约0.05秒)
- 按 E 或 ESC 关闭文本
- 文本显示期间角色可以缓慢移动(不硬锁定)
---
## 交互对象数据结构
每个可交互物体需要以下信息:
```json
{
"id": "fridge_home",
"name": "旧冰箱",
"type": "examine",
"triggerRadius": 1.5,
"interactText": "查看旧冰箱",
"narrativeText": [
"夏天的时候最期待打开冰箱的那一刻。",
"冰棒、西瓜、偶尔还有一瓶健力宝。",
"现在想起来,那个冰箱的嗡嗡声好像还在耳边。"
],
"oneShot": false
}
```
- `oneShot: true` 表示只触发一次(如拾取物品、一次性事件)
- `oneShot: false` 表示可反复交互(如观察类),但文本可以随机变化
---
## v0.1 交互对象清单
> 程序 Agent 按分阶段顺序实现。第一轮跑通系统,第二轮填充体验。
### 第一轮:系统验证(5 个,优先实现)
覆盖全部 4 种交互类型,跨 3 个区域,验证核心流程。
| # | ID | 名称 | 类型 | 区域 | 验证目标 |
|---|---|---|---|---|---|
| 1 | fridge_home | 旧冰箱 | 观察 | 家 | 室内大件观察,相机推镜 + 内心独白文案 |
| 2 | door_home | 家的门 | 操作 | 家 | 最简操作交互,门开↔关状态切换 |
| 3 | ground_marble | 散落的弹珠 | 拾取 | 空地 | 拾取完整流程:提示→弯腰→消失→计数+1 |
| 4 | phone_booth | 公用电话亭 | 观察 | 街道 | 室外独立物体观察,户外推镜体验 |
| 5 | owner_shop | 老板 | NPC | 小卖部 | 走向人→推镜→场景描述文本 |
**探索路线**: 家(冰箱→门)→ 街道(电话亭)→ 小卖部(老板)→ 空地(弹珠)
### 第二轮:体验填充(5 个,系统跑通后追加)
验证多交互物并存、不同物体形态的推镜差异。
| # | ID | 名称 | 类型 | 区域 | 补什么体验 |
|---|---|---|---|---|---|
| 6 | tv_home | 老式电视 | 观察 | 家 | 同区域第二件观察物,验证不冲突 |
| 7 | shelf_snack | 零食货架 | 观察 | 小卖部 | 矮物体推镜角度,近距离观察 |
| 8 | ground_card | 水浒卡碎片 | 拾取 | 空地 | 第二个拾取品,验证不互相干扰 |
| 9 | wall_graffiti | 墙上的涂鸦 | 观察 | 街道 | 墙面类物体,水平推镜方向 |
| 10 | box_alley | 废纸箱 | 操作(翻找) | 巷子 | 第二种操作类型,与门不同 |
### 后续版本(v0.1 可选,不阻塞验收)
以下交互物在第一轮 + 第二轮全部完成后,视开发进度按区域补充:
| 区域 | ID | 名称 | 类型 |
|------|---|---|---|
| 家 | bed_home | 我的床 | 观察 |
| 家 | desk_home | 书桌 | 观察 |
| 家 | calendar_home | 日历 | 观察 |
| 小卖部 | shelf_drink | 冰柜 | 观察 |
| 小卖部 | card_rack | 卡片架 | 观察 |
| 街道 | bike_street | 老式自行车 | 观察 |
| 街道 | laundry | 晾衣杆 | 观察 |
| 街道 | manhole | 下水道盖 | 观察 |
| 空地 | ground_stone | 小石子 | 拾取 |
| 空地 | tree_empty | 大树 | 观察 |
| 空地 | puddle | 水坑 | 观察 |
| 巷子 | cat_alley | 流浪猫 | 观察 |
| 巷子 | window_alley | 老窗户 | 观察 |
| 巷子 | spider_alley | 蜘蛛网 | 观察 |
| 水塘边 | pond_edge | 水塘 | 观察 |
| 水塘边 | frog_pond | 青蛙 | 观察 |
| 水塘边 | reed_pond | 芦苇 | 观察 |
| 水塘边 | ground_wrapper | 糖纸 | 拾取 |
| 水塘边 | ground_eraser | 橡皮擦 | 拾取 |
---
## 白盒方案
v0.1 使用近似占位模型而非纯不可见触发区域,以便调试相机推镜距离、空间关系和交互体验。
**原则**:
- 找免费 lowpoly 模型或 UE Marketplace 免费素材,形状和比例大致对即可
- 冰箱用方箱子、自行车用简单两轮模型,不要求贴图精确
- 后续美术阶段替换为正式资产
**交互物占位模型需求**(按实现阶段排列):
**第一轮(必须)**:
| ID | 交互物 | 占位模型建议 |
|---|--------|------------|
| fridge_home | 旧冰箱 | 白色方箱子(~1.7m 高) |
| door_home | 家的门 | 扁平方片,可绕轴旋转 |
| ground_marble | 散落的弹珠 | 小球体,+ 地面光斑 |
| phone_booth | 公用电话亭 | 窄高方柱(~2m 高) |
| owner_shop | 老板(NPC) | 简单人形胶囊体,坐姿 |
**第二轮(追加)**:
| ID | 交互物 | 占位模型建议 |
|---|--------|------------|
| tv_home | 老式电视 | 方箱 + 凸起背部(~0.5m 高) |
| shelf_snack | 零食货架 | 多层架结构(~1.8m 高) |
| ground_card | 水浒卡碎片 | 小方片,+ 地面光斑 |
| wall_graffiti | 墙上的涂鸦 | 墙面贴花/色块 |
| box_alley | 废纸箱 | 开口方箱(~0.5m 高) |
---
## v0.1 不包含
- 对话树 / 对话分支系统
- 物品背包 UI(物品拾取后只计入收集计数)
- 物品使用/组合系统
- NPC AI(NPC 为静态站位)
- 交互对象的动画变化(如开门后门保持打开)
- 时间相关的交互变化