← 返回首页
2019 · GDC · Insomniac Games

《漫威蜘蛛侠》AI 复盘:失眠组如何重构战斗 AI,让「你就是蜘蛛侠」成为必然

🤖 战斗AI🧩 数据驱动🕷️ 电影感战斗
核心观点

「做过《日落过载》就以为会做战斗?失眠组被《漫威蜘蛛侠》狠狠上了一课——64 种 AI 类、30 个活跃敌人上限,从行为树到数据驱动,全靠一次彻底的 AI 重构。」

原标题'Marvel's Spider-Man' AI Postmortem
作者简介 Adam Noonchester · Insomniac Games 首席玩法程序员(Lead Gameplay Programmer),在 GDC 2019 上复盘《漫威蜘蛛侠》的战斗与敌人 AI 开发;工作室此前代表作有《瑞奇与叮当》《日落过载》《抵抗》等动作游戏。

开场:一次被现实打脸的复盘

  • 自认会做战斗:Insomniac 做过《瑞奇与叮当》《日落过载》《抵抗》等动作游戏,团队以为「知道怎么做战斗、能立刻上手」——复盘的第一句就是「他们错了」。
  • 更大项目、更小团队:《漫威蜘蛛侠》是工作室史上规模最大的项目,开发团队反而比《日落过载》更小,且跑在 2012 年起自研的 C++ 引擎上。
  • 规模爆炸:游戏有 5 个主要敌人派系加数个小派系,每个派系 8 种通用战斗风格(主要派系还有变体与专属风格),最终折算为 64 种不同 AI 类;而体量更大的《日落过载》只有 19 个 AI 类、17 个行为树。

从行为树到数据驱动:机器人指令系统

  • 旧架构的账:行为树生成行为节点,节点输出角色状态,树再控制动画与移动;一个远程敌人的简单子行为树就有 34 个节点。
  • 反模式堆叠:「站在栏杆旁向外射击」这种简单行为要 5 个回调函数;节点选择逻辑催生大量修饰器与含义不明的标识。
  • 为什么弃用:AI 能跑,但结构复杂、出错难查,封装好的节点无法复用,数据驱动占比越来越高——于是整体转向数据驱动方案。
  • 高层架构:脚本创建总控节点 BotCommand,命令进入机器人命令序列 BotCommandQueue,行为树逐条拉出命令(StartBehavior)创建子行为或状态。
  • 运行机制:Update 在指令完成后弹出队列,再调 ConsumeNextCommand 取下一条,队列为空即停止。
  • 实例串链:请求控制机器人 → 前往位置 → 面向目标 → 播放动画,就能串起复杂行为。
  • 收益与代价:加新技能不用改转换逻辑、状态与数据宽松匹配、可筛选开放给设计师的数据;缺点是数据结构混乱,如近战实例里的 if-else 嵌套。

数据驱动的近战连招系统

  • 数据层四件套:机器人连招配置 → 连招列表 BotComboEntry → 技能组合包 BotComboMoveContainer → 基础技能节点 ComboMoveBase(承载静态数据:动画、攻击时机、子弹发射点等)。
  • 行为层状态机:行为树生成近战攻击行为,进战时把连招数据交给 BehaviorUseCombo(本质是等待/移动/施放/停止的状态机),由组合包元数据(是否需要看到玩家、是否在屏幕内、施放距离)驱动状态转换与冷却。
  • 选招逻辑:BotComboEntry 含冷却、连招权重、最大/最小距离,负责对当前目标选最优连招、按权重生成连招序列;BehaviorMelee 是实际使用连招的标准状态机。
  • 覆盖面:游戏用这套结构处理了全部 37 种技能连招类型;数据驱动覆盖近战攻击、脚本控制的敌人行为、受击表现、格挡/闪避/反击四大模块。

同步关节:做出电影感战斗

  • 漫改电影感:创意总监要求战斗与受击动画高度真实,系统把角色分成主体(攻击发起者)与客体(被攻击者),播放蜘蛛侠与互动对象成对的动作。
  • 同步关节:附加在主体上的额外关节点(含位置与朝向),播同步动画时与目标匹配对齐;主要用主体关节,蜘蛛侠能对还没播反应动作的角色直接发起同步攻击。
  • 三种对齐策略:主体客体连线旋转面向彼此(最常用,用于投技调方向);客体被拉入主体位置(蜘蛛侠不动);蜘蛛侠主动位移进目标位置(绝大多数攻击)。
  • 高度差处理:同步点/释放点标记,表演镜头拉近摄像机隐藏漂浮;用蛛丝动画程序化调整;移动系统保持开启,碰撞障碍物时跳过位移指令、敌人直接平移。
  • 代价:同步攻击越多,受击方越常播受击动画而显不公平;无法一次终结多个目标;每加一套新骨骼都要补同步攻击动画,成本高。

战斗节奏:指令标记与战斗管理器

  • 目标:高速、流畅、动感——既让敌人有威胁,又让玩家能打流畅连招;近战与远程各有一个战斗管理器控制攻击时机。
  • 初版两个标记:攻击指令(玩家刚闪避就不攻击,留喘息窗口);优先级公式 = 已等待攻击时间 + 到理想攻击位置的距离 + 小 boss 额外值。
  • 初版问题:玩家不会在计时点立刻受击,长时间遭遇战容易预测。迭代加入指令窃取(能立刻攻击的怪可抢指令)、近距离指令(玩家贴怪超 1 秒可新建攻击指令)、战斗烈度计(攻击与分发指令时累计/消耗,控制爆发)。
  • 远程参数:攻击窗口、指令上限、延迟时间、冷却窗口。
  • 屏幕外远程攻击:先改为只给屏幕内远程敌人发指令、全出屏时失效;最终方案是屏幕外敌人攻击间隔更长——屏幕外蜘蛛感应预警 1.5 秒,屏幕内仅 0.75 秒。
  • 空中连招呆滞:近战远程混战调高冷却后,空中连招时敌人约 5 秒才反应、显得呆;引入空中进攻(Air Aggression Chance):玩家空中连招时攻击概率渐升,到 0.5 时周围敌人 50% 概率出手。
  • 仍被集火:加攻击取消列表(执行列表指令即取消所有未执行攻击指令,boss 战除外,过度重复除闪避外的指令才恢复攻击);再加先发制人(Beat-To-The-Punch):打击帧开启时检测来袭攻击,若己方攻击能强制敌人受击,则打击帧期间免疫——同时出手时蜘蛛侠总是先命中。

站位、特殊敌人与性能上限

  • 站位的两次试错:射击游戏旧做法是预标记开火位加体积遮挡;本作需求是与大群敌人战斗却不觉得被围攻。首试在蜘蛛侠周围生成楔形区域、环形半径外扩并检测寻路有效性——玩家一动就全失效,机器人不停换位且寻路机械。
  • 梯度下降终案:定义机器人自留区(个人空间红圈)加 NavMesh 边界,能量规则是红圈内推出、NavMesh 外推回;每次传入 5 个点(目标连线前后各一、过目标垂线左右各一、当前位置),按评分公式(DistanceCurrent、DistanceTarget、ClosePenalty、FarPenalty、CrossOverPenalty)取最低分。
  • 圈层补丁:中型遭遇战表现好、大型战与增援刷怪差,于是恢复部分区域环,不分配具体站位而分配距离信息——内圈高优先区最多 6 人,外圈人人可站。
  • 迟滞机制:比较「当前位置到理想攻击位距离 − 新位置到理想攻击位距离」与随时间变化的阈值,位移落在后退/前进滞后值之间才动,停滞越久越可能移动,用来避免来回抖动。
  • 网毯:6×6 格子关节的蛛网模型,用于把敌人困在不平整表面;从生成位置上方发射射线定位关节附着点,未命中则向初始位置旋转包裹,持续扫描以适配布娃娃,附着对象移远时重新扫描。
  • 鞭索敌人:常规衣物模拟不够、又需复用其他职业动画,改用程序化方案、必要时切换动画控制;限制器链由距离限制器(0-1 硬度、上下各半矫正)、弯曲度限制器(防下垂打结)、胶囊体限制器(防穿体)与地面组成,实际执行顺序是 中立→弯曲度→胶囊体→距离→地面;模拟与动画以 0-1 融合速度事件切换,任何关节不同时受两者控制,浮空对齐比例随关节离发射点越远线性增长,实现「从空中拉下蜘蛛侠」。
  • 飞行与载具:飞行敌人(喷气兵、电光人、秃鹫)漂浮于 NavMesh 之上、可飞出范围,靠路点返回仍会绕障碍转圈,用红色胶囊物理检测判断能否直线接近;飞行 boss 用样条连接的体积集合活动,但数据需手动生成、不通用。卡车等移动载具战中 NavMesh 无法移动只能简化战斗区域,引擎不支持附着物件需手动更新,用移动中的杀伤体积解决被扔下车的单位穿模。
  • 开放世界 NavMesh:曼哈顿随剧情实时变化,运行时生成 CPU 成本过高,改为预生成最复杂版本、用脚本按章节开关补丁数据。
  • 性能上限:最大活跃敌人限制为 30 个——物理与多核分摊成本随机器人数量上涨;大量核心 AI 逻辑仍跑在主线程,机器人逻辑单帧消耗超 4 毫秒。

✦ 一句话总结:Insomniac 用一场彻底的数据驱动重构把 64 种 AI 类、30 个活跃敌人收进同一套系统,让「你就是蜘蛛侠」从目标变成必然。