# 环境交互系统 — 设计文档 > 对应程序实现:交互组件基类、交互检测、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 为静态站位) - 交互对象的动画变化(如开门后门保持打开) - 时间相关的交互变化