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 项目 One Sheet 主视觉

概览

两个人控制一条龙:一个人用身体的动作和倾斜驾驶龙,另一个人作为骑手用摇杆移动、拉绳出手。DragonRider 是一个 Unreal Engine 5.6 的第三人称动作 / 飞行原型,配一套自制的 ESP32 体感控制器。

这是 2026 年上半年在犹他大学 EAE 的一个 14 人团队项目,三个设计支柱是协作、感官体验、快节奏。我是团队里的客户端工程师。

14人团队
36份试玩问卷,全部评价为“好”或“很好”
19 B的二进制数据包,控制器每 10 ms 发一次
4个 Boss 技能,全部走 GAS

我负责什么

  • 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% 的人认为最需要改进,战斗这一层基本没有成为体验上的问题