这是一个“硬件输入驱动玩法”的 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

输入 → 运动的主链路:

  1. 串口 IMU 数据读取(或键盘模拟)
  2. 滤波与 deadzone:平滑角速度,过滤抖动
  3. 头部→方向:将 yaw 角速度映射成 headOffsetDeg(夹在 ±35°),驱动 yawRotateTarget 转向
  4. 尾部→速度:用 sweep 检测器识别“扫尾峰值与频率”,提升 forward speed,并在无扫尾时指数衰减回基础速度
  5. 协作手势:在时间窗内检测头尾反向配对,触发 90°转向;头尾同时上/下触发 跳跃/下蹲
  6. 工程化接口:外部系统可叠加 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 或重新打包。


快速上手(复现路径)

  1. Windows 打开 Unity 项目(2023.1.22f1)
  2. 场景中放置两条龙(A/B),每条龙根节点挂:
    • CoopDragonMovement
    • CoopDragonSkills
  3. 互相绑定 opponent 引用:A.opponent → B,B.opponent → A
  4. F1 打开串口菜单,为 A/B 分别选择 head/tail COM 并 Apply
    (无硬件:开启键盘方案,A 用 WASD,B 用方向键)
  5. 放置 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