Work / Gameplay Prototype
DragonRider UE5 双人体感骑龙原型
两个人骑一条龙:体感控制器驱动飞行,GAS 组织战斗与 Boss 技能。我负责 GAS、敌人 AI 和硬件调试。
- Role
- 客户端工程师(GAS · AI · 硬件调试)
- Year
- 2026
- Team
- 14 人团队 · 犹他大学 EAE
- Tech
- Unreal Engine 5.6 · C++ / Blueprint · GAS · ESP32
- Status
- 原型

概览
两个人控制一条龙:一个人用身体的动作和倾斜驾驶龙,另一个人作为骑手用摇杆移动、拉绳出手。DragonRider 是一个 Unreal Engine 5.6 的第三人称动作 / 飞行原型,配一套自制的 ESP32 体感控制器。
这是 2026 年上半年在犹他大学 EAE 的一个 14 人团队项目,三个设计支柱是协作、感官体验、快节奏。我是团队里的客户端工程师。
我负责什么
- GAS 战斗框架:玩家和敌人的 AbilitySystemComponent、属性集、GameplayEffect 库
- 敌人与 Boss 的 AI:巡逻 / 追击状态、Boss 的技能与阶段切换
- 硬件调试:把控制器接进游戏、让输入稳定可用的那一段联调
GAS:把数值和状态从蓝图里抽出来
玩家和敌人都不靠临时的 if-else 堆战斗,属性、效果和能力统一交给 Gameplay Ability System。
| 类 | 作用 |
|---|---|
AGASDragonCharacterBase |
玩家基类,实现 IAbilitySystemInterface,初始化 ASC 与属性集 |
UGASBaseAttributeSet |
Health / MaxHealth / Energy / MaxEnergy / Gold,通过 RepNotify 复制 |
AEnemyBase |
敌人基类:AI 状态(Patrol / Chase)、死亡逻辑、GAS 初始化 |
UEnemyAttributeSet |
敌人的 Health 与 AttackPower |
数值和状态都放在 GameplayEffect 里,而不是写在能力蓝图中,这样调数值不用改能力:
GE_InitBoss/GE_InitPlayer:生成时初始化属性GE_Dmg_Boss_*:每个 Boss 技能各自的瞬时伤害GE_SwitchStatus:用 Gameplay Tag 管理二阶段和无敌状态
敌我识别走 Generic Team ID,不硬编码阵营。
Boss 的四个技能
| 能力 | 机制 | 表现 |
|---|---|---|
GA_Boss_ArcaneBarrage |
PlayMontageAndWait + GE |
动画驱动,触发开始施法的效果 |
GA_Boss_ArcaneBombardment |
随机 AOE 循环 | 在指定半径内计算多个落点 |
GA_Boss_FocusedBeam |
按 tick 做射线检测 | 对视线上的目标周期性施加伤害 |
GA_Boss_HomingOrb |
空间变换计算 | 在施法者周围生成追踪弹 |
控制器到 Unreal 的输入链路
控制器是一块 ESP32,把几种物理输入融合成一个数据包:
| Offset | 类型 | 字段 | 含义 |
|---|---|---|---|
| 0 – 1 | uint8 × 2 | Header | 固定 0xAA 0xBB,用来对齐 |
| 2 | float | Dragon Speed | 0.0 – 1.0,由“龙翼”传感器的总加速度归一化 |
| 6 | float | Dragon Dir | −1.0 – 1.0,由“身体”传感器的 Roll 角归一化,±30° 满量程 |
| 10 / 14 | float × 2 | Rider X / Y | 摇杆,死区 0.15 |
| 18 | uint8 | Events | 位掩码;压力传感器超过阈值时置位“拉绳” |
Unreal 一侧由 UAltControlClientComponent 以 100 Hz 从本地地址拉取数据包,解析成 FAltGamePacket;角色蓝图监听 OnPacketUpdated,用 FInterp To 对 Yaw / Pitch / Roll 的速率做平滑,否则原始传感器噪声会让龙“抽搐”。项目同时保留了键盘输入路径,没有硬件时可以照常开发和测试。
硬件上反复遇到的几类问题,最后都写进了排查表:
- 开机 LED 一直闪:两块 MPU6050 至少一块没找到。固件宁可拒绝启动,也不进入“能跑但输入是错的”状态
- 角度漂移:开机校准要采 500 次样,期间控制器必须静止
- 压力传感器没反应:阈值设得太高(1023 满量程里取了 1000)
项目的整体结构
代码按三层拆开,方便 14 个人并行:
- 输入层:PlayerController 管理键盘 / 手柄的输入映射;
UAltControlClientComponent桥接硬件 - 物理与移动层:角色移动,以及
UDragonBounceComponent——龙撞到地形时做速度反射而不是硬停,低于MinImpactSpeed的擦碰不触发,避免抖动 - 战斗与能力层:上面的 GAS 与 AI
属性通过 RepNotify 复制,支持同步的双人合作。版本管理用 Perforce。
试玩结果
一次试玩收了 36 份问卷,21 人扮演龙,15 人扮演骑手。
| 问题 | 结果 |
|---|---|
| 整体体验 | 很好 41.7%,好 58.3%,一般和差为 0 |
| 控制器最需要改进的 | 操控手感 91.7%,舒适度 8.3%,安全 0 |
| 内容最需要改进的 | 教程 52.8%,隧道穿越 25.0%,Boss 战 19.4%,更多双人协作 2.8% |
好评集中在美术和“好玩”上。问题也很一致:龙的操控被形容为“重”“晃”“不灵敏”“有延迟”,而且不看教程很难弄明白怎么操作。
回头看
- 九成的人把票投给“操控手感”。滤波和平滑压住了传感器噪声,也压住了响应——体感输入的手感需要比按键输入多得多的调参时间
- 教程是最大的短板。体感控制器的学习成本比手柄高得多,这件事应该在项目早期就算进去
- Boss 战只有 19.4% 的人认为最需要改进,战斗这一层基本没有成为体验上的问题
Read by Focus