Files
ChildHood/docs/design/systems/interaction-system.md
T
2026-06-01 17:55:36 +08:00

297 lines
10 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 交互对象清单
按场景区域划分(配合 scene-v01-suburban.md):
### 家
| ID | 名称 | 类型 | 描述 |
|---|---|---|---|
| fridge_home | 旧冰箱 | 观察 | 夏天的冰箱记忆 |
| tv_home | 老式电视 | 观察 | 大脑袋电视,天线要调 |
| bed_home | 我的床 | 观察 | 床底下的宝藏箱 |
| desk_home | 书桌 | 观察 | 没写完的暑假作业 |
| calendar_home | 日历 | 观察 | 圈着"开学的日期",被划掉了又画上 |
### 小卖部
| ID | 名称 | 类型 | 描述 |
|---|---|---|---|
| door_shop | 小卖部门 | 操作 | 进出小卖部 |
| shelf_snack | 零食货架 | 观察 | 辣条、泡泡糖、干脆面…… |
| shelf_drink | 冰柜 | 观察 | 健力宝、北冰洋、袋装冰 |
| owner_shop | 老板 | 观察(NPC) | 打瞌睡的老板和电视声 |
| card_rack | 卡片架 | 观察 | 水浒卡、数码宝贝卡片 |
### 街道
| ID | 名称 | 类型 | 描述 |
|---|---|---|---|
| phone_booth | 公用电话亭 | 观察 | IC卡电话的回忆 |
| bike_street | 老式自行车 | 观察 | 爸爸的永久牌 |
| laundry | 晾衣杆 | 观察 | 满院子飘着的衣服 |
| wall_graffiti | 墙上的涂鸦 | 观察 | 不知谁画的奥特曼 |
| manhole | 下水道盖 | 观察 | 弹珠掉进去的声音 |
### 空地
| ID | 名称 | 类型 | 描述 |
|---|---|---|---|
| ground_marble | 散落的弹珠 | 拾取 | 彩色花纹弹珠 |
| ground_card | 水浒卡碎片 | 拾取 | 被踩脏的卡片 |
| ground_stone | 小石子 | 拾取 | 打水漂用的石头 |
| tree_empty | 大树 | 观察 | 爬不上去的梧桐树 |
| puddle | 水坑 | 观察 | 昨天下的雨还没干 |
### 巷子
| ID | 名称 | 类型 | 描述 |
|---|---|---|---|
| cat_alley | 流浪猫 | 观察 | 巷子深处的猫 |
| window_alley | 老窗户 | 观察 | 窗台上的花盆 |
| box_alley | 废纸箱 | 操作(翻找) | 可能藏着好东西 |
| spider_alley | 蜘蛛网 | 观察 | 角落里的蛛网 |
### 水塘边
| ID | 名称 | 类型 | 描述 |
|---|---|---|---|
| pond_edge | 水塘 | 观察 | 水面倒映着天空 |
| frog_pond | 青蛙 | 观察 | 荷叶上的青蛙 |
| reed_pond | 芦苇 | 观察 | 风吹过的沙沙声 |
| ground_wrapper | 糖纸 | 拾取 | 彩色的糖纸 |
| ground_eraser | 橡皮擦 | 拾取 | 用了一半的橡皮 |
---
## 白盒方案
v0.1 使用近似占位模型而非纯不可见触发区域,以便调试相机推镜距离、空间关系和交互体验。
**原则**:
- 找免费 lowpoly 模型或 UE Marketplace 免费素材,形状和比例大致对即可
- 冰箱用方箱子、自行车用简单两轮模型,不要求贴图精确
- 后续美术阶段替换为正式资产
**交互物占位模型需求**:
| 区域 | 交互物 | 占位模型建议 |
|------|--------|------------|
| 家 | 旧冰箱 | 白色方箱子(~1.7m 高) |
| 家 | 老式电视 | 方箱 + 凸起背部(~0.5m 高) |
| 家 | 书桌 | 长方体桌面 + 四腿(~0.75m 高) |
| 家 | 日历 | 薄长方体贴墙(~0.4m 高) |
| 家 | 床 | 扁平长方体(~0.5m 高) |
| 小卖部 | 零食货架 | 多层架结构(~1.8m 高) |
| 小卖部 | 冰柜 | 矮宽方箱(~0.9m 高) |
| 小卖部 | 卡片架 | 窄薄立架(~1.2m 高) |
| 小卖部 | 老板(NPC) | 简单人形胶囊体,坐姿 |
| 街道 | 公用电话亭 | 窄高方柱(~2m 高) |
| 街道 | 老式自行车 | 简单车形(两轮 + 车架) |
| 街道 | 晾衣杆 | 长杆 + 几块平面(衣物) |
| 空地 | 大树 | 圆柱树干 + 球形树冠 |
| 空地 | 水坑 | 扁平圆形,反光材质 |
| 巷子 | 流浪猫 | 小型胶囊体,低矮 |
| 巷子 | 废纸箱 | 开口方箱(~0.5m 高) |
| 水塘 | 青蛙 | 极小胶囊体 |
| 水塘 | 芦苇 | 几根细圆柱簇 |
| 拾取品(通用) | 弹珠/卡片/糖纸等 | 小球/小片,+ 地面光斑 |
---
## v0.1 不包含
- 对话树 / 对话分支系统
- 物品背包 UI(物品拾取后只计入收集计数)
- 物品使用/组合系统
- NPC AI(NPC 为静态站位)
- 交互对象的动画变化(如开门后门保持打开)
- 时间相关的交互变化