这是一个“硬件输入驱动玩法”的 Unity 原型:每条龙由两名玩家协作控制(头 + 尾),用 IMU 陀螺仪角速度(deg/s)通过串口输入来驱动转向、加速、90°协作转向、跳/蹲以及近战技能与拾取触发。
目标是把「输入 → 行为 → 反馈 → 对抗/协作」做成可调参、可复用、可扩展的玩法骨架,而不是一次性的 Demo。
关键词
- 硬件输入工程化:Windows
System.IO.Ports串口读取 IMU(后台线程 + 队列),支持 3/4 列 CSV,容错忽略噪声/头信息 - 双人协作输入映射:头控方向(±35°偏移),尾控速度(sweep 检测加速),双人手势触发 90°转向 / 跳跃 / 下蹲
- 可调参的运动系统:deadzone / smoothing / 灵敏度 / 最大转向速度 / 速度衰减 / 冷却窗口等参数全部 Inspector 可调
- 对抗技能系统:Attack(咬住挂载 + 挣脱窗口)、Interfere(毒/反转控制)、Protect(护盾自动触发)
- 拾取与场景互动:技能拾取(SkillPickup)、加速环(SpeedRing)、陷阱环 QTE(TrapRing)、阻挡器(Blocker)
- 运行时设备配置:串口选择菜单(F1)支持双龙四个 COM(A/B 的 head/tail),并用 PlayerPrefs 记忆配置
- 可测试性:完整键盘测试方案(无硬件也能复现逻辑),并支持每龙独立键位映射
- 风险清单与规避:Trigger 不触发、模型轴向不一致、串口被占用、Y 轴锁定被物理破坏、咬住挂载抖动等都有明确规避策略
项目概述
- 两条龙(Dragon A / Dragon B),每条龙由两名玩家控制:
- Head IMU:控制朝向(小幅连续转向 + 协作手势)
- Tail IMU:控制速度(扫尾频率/幅度→加速)+ 协作手势
- 支持键盘替代输入:便于无硬件时调试/演示
- 技能系统采用“单槽位”设计:拾取后占用当前技能;Protect 立即触发护盾;Attack/Interfere 近距离瞄准触发
Unity 版本:2023.1.22f1(Windows Editor/Standalone 推荐,串口仅 Windows 可用)。
核心系统拆解(对应代码)
1) 运动系统:CoopDragonMovement
输入 → 运动的主链路:
- 串口 IMU 数据读取(或键盘模拟)
- 滤波与 deadzone:平滑角速度,过滤抖动
- 头部→方向:将 yaw 角速度映射成
headOffsetDeg(夹在 ±35°),驱动yawRotateTarget转向 - 尾部→速度:用 sweep 检测器识别“扫尾峰值与频率”,提升 forward speed,并在无扫尾时指数衰减回基础速度
- 协作手势:在时间窗内检测头尾反向配对,触发 90°转向;头尾同时上/下触发 跳跃/下蹲
- 工程化接口:外部系统可叠加
externalSpeedAdd / externalSpeedMultiplier(用于加速、减速、眩晕等效果)
设计要点:
- 所有关键阈值(deadzone、sweep threshold、turn window、cooldown、最大速度、衰减速度等)都可调,利于做“手感调参”。
2) 串口协议与容错:内置解析器(Movement 内的 SerialIMU)
支持两种 CSV 格式:
time_ms,gx,gy,gz(推荐)gx,gy,gz
并会忽略:
- 以
time开头的 header 行 - 含有
WHO_AM_I / I2C的调试行
实现方式:
- 后台线程
ReadLoop()读串口行 → 入队列 - 主线程
DrainLatest()每帧取“最新有效一条”,避免堆积造成延迟
3) 技能系统:CoopDragonSkills + SkillPickup
技能槽位枚举:
Attack:咬住挂载(latch)+ 挣脱窗口(escape sweeps / timing window)Interfere:施加干扰(毒/控制反转等负面效果;护盾可抵消)Protect:护盾(拾取后立即触发,持续指定秒数)
关键工程点:
- 近战技能不是“按一下就中”,而是有 距离 + 朝向角 + 按住触发时长 的判定,减少误触、便于调参。
- 挂载跟随放在
LateUpdate():保证受害者先移动完,降低抖动。
4) 场景互动脚本:环/陷阱/阻挡
SpeedRing:触发后调用ApplySpeedBoost(additive, duration),并带 cooldown + 特效重启TrapRing:触发后StopForStun(stunDuration, qteTarget),通过 QTE 挣脱Blocker:短暂阻挡(Blocked),触发后销毁自身SkillPickup:拾取技能,支持拾取特效 pulse、销毁/禁用两种模式
这些脚本都遵循同一模式:OnTriggerEnter → 找到龙的 Skills 组件 → 调用统一 API,保持系统边界干净。
5) 运行时串口选择菜单:CoopSerialPortMenu
- F1 弹出配置 UI(支持暂停 Time.timeScale)
- 自动读取 COM 列表,分别设置 Dragon A/B 的 head/tail
- 可选自动保存/自动应用(PlayerPrefs)
价值:演示与部署友好——换一台机器只要重新选 COM,不需要改 Inspector 或重新打包。
快速上手(复现路径)
- Windows 打开 Unity 项目(2023.1.22f1)
- 场景中放置两条龙(A/B),每条龙根节点挂:
CoopDragonMovementCoopDragonSkills
- 互相绑定 opponent 引用:A.opponent → B,B.opponent → A
- F1 打开串口菜单,为 A/B 分别选择 head/tail COM 并 Apply
(无硬件:开启键盘方案,A 用 WASD,B 用方向键) - 放置
SkillPickup / SpeedRing / TrapRing / Blocker测试拾取与交互
已知风险点(以及我如何规避)
- 拾取触发不生效:Trigger 需要至少一方有 Rigidbody;检查 IsTrigger 与 Layer Collision
- 模型轴向不一致:不要直接驱动模型子物体;驱动 parent,并正确设置
forwardAxis - 串口被占用/无数据:关闭 Arduino Serial Monitor;确认波特率与输出格式一致
- Y 轴锁被物理破坏:尽量避免在运动根节点挂 Rigidbody;必要时在 FixedUpdate 锁 Y
- 咬住挂载抖动:挂载跟随放 LateUpdate;避免物理力干扰;必要时冻结攻击方输入/移动
技术栈
- Unity 2023.1.22f1
- C#(MonoBehaviour 系统)
- Windows
System.IO.Ports(串口) - 多线程读串口(Thread + ConcurrentQueue)
- PlayerPrefs(配置持久化)
下一步迭代方向(如果继续产品化)
- 抽离输入层接口:IMU / 键盘 / 手柄统一为同一套 Input Provider
- 引入确定性回放(record/replay):记录 IMU 输入序列,便于回归测试与演示
- 技能系统数据驱动:把参数从 Inspector 迁到 ScriptableObject,方便做平衡表
- 更完善的 UI/反馈:命中提示、挣脱计数、护盾剩余时间、控制反转提示等
链接
- Demo 视频:TODO
- Repo:TODO
- 设计说明:TODO