在上一篇 《AI 原生游戏开发实践 · 把游戏角色模型逆向进引擎》 里,我把某第三人称射击游戏的角色与怪物资产——网格、骨骼、材质——从封包里逆向进了引擎。那篇的重心是”资产能不能导进来、导得对不对”。
但资产只是躯壳。一只怪物如何产生可信的运动表现,取决于它背后的动画系统。这篇就把那层拆开——重点是怪物:一只只风格迥异的敌人,它们的动画到底是怎么组织、怎么驱动、怎么控制成本的。
分析样本是几只风格完全不同的敌人。为避免可能不准确的中文译名,下文一律沿用其内部标识:一只标准步兵(Conscript)、一只中型冲锋兽(Charger)、一只飞行 BOSS(Dragonroach)、一只精英军官(Commissar)、一只被感染的人形(Corrupted)。它们跨三个阵营,体型从人形到巨兽,行为从冲锋到飞行。
我想用它们的实测数据回答几个具体问题:
- 一只怪物的动画,是”逐段选择播放”,还是别的组织方式?
- 同一只怪装备不同武器,动画是各做一套,还是可以复用?
- 不同怪物之间,动画共享吗?
- 哪些动作是美术逐帧制作的资源,哪些是运行时程序合成的?
- 体型、定位不同的怪,动画策略差在哪?
定位与合规声明 · 本文是怪物动画系统的学习与分析记录,延续上一篇的方法:用一个真实但匿名的案例,理解一个无文档的黑盒系统是如何设计的。文中一律以”某第三人称射击游戏””目标引擎”代称,不点名具体作品,不公开任何封包细节。分析对象是”动画系统如何设计”,与是否为特定游戏无关——任何一款现代 3A 的角色动画都可作如是观。需要说明的是:这类逆向素材里,动画大多是哈希命名的(无可读名),部分语义只能从状态结构中反推,因此文中一些结论标注为”推断”——诚实标注,好过假装精确。
本文不谈”如何把这些数据挖出来”的技术细节(那是工具的事),只谈挖出来之后看到了什么——一个 3A 怪物动画系统的设计全貌。
一、动画不是”逐段选择”,是”分层混合”
最容易的误解,是把角色动画理解成一台录像机:美术做好”移动””开火””死亡”一批片段,运行时按逻辑选择其一播放,一次一个。
这个模型从根上就错了。 真实的角色动画,靠的是分层混合(Layered Blending)。
以中型冲锋兽 Charger 为例。它的动画不是”逐段挑选播放”,而是多个动画层(Animation Layer)同时求值,每一层独立算出它对骨骼姿态的贡献,再从底向上逐层合成(Composite)出最终这一帧,送去渲染。
层与层之间如何合成,取决于该层的混合模式(Blend Mode)——这是整套系统的核心区分:
覆盖层(Override Layer) —— 输出完整的骨骼姿态,在其作用的骨骼上覆盖下层结果。例如基础层驱动全身”奔跑”,上层将上半身覆盖为”持械瞄准”:上半身骨骼被替换为瞄准姿态,下半身维持奔跑。
叠加层(Additive Layer) —— 不输出完整姿态,只输出一个相对参考姿势的增量(Delta),叠加到下层结果之上。以开火后坐为例:该层不定义手臂的绝对位置,而是输出”在当前姿态基础上,枪口产生的位移增量”。因此单位在移动中开火时,移动姿态完整保留,仅叠加一层后坐反馈(Recoil)。
理解了这两种混合模式,”移动、瞄准、受击同时发生”这件事就清楚了。一只单位在奔跑中被击中,它的最终姿态由三层合成:
- 下半身移动 —— 覆盖层,仅作用于下半身骨骼。
- 上半身持械 —— 覆盖层,仅作用于上半身骨骼。
- 受击反馈 —— 叠加层,在上述结果之上叠加一个受击增量。
三层各自独立求值,同时输出,合成为一个”移动 + 持械 + 受击”的复合姿态——而这个复合姿态,美术从未单独制作过。它是运行时实时合成的。

这里还有一个不讲清就会误解的机制:骨骼遮罩(Bone Mask)。
上文说”上半身持械层仅作用于上半身骨骼”,凭什么它不影响腿部?靠的正是骨骼遮罩——每个动画层可以声明它只作用于骨骼的一个子集。实测怪物的下半身移动层,几乎每个状态都带遮罩(仅驱动腿部);上半身层同样几乎全带遮罩(仅驱动上肢)。正因不同层作用于不同的骨骼集合,它们才能同时叠加而互不干涉。
所以”覆盖层”这个说法要严格化:它不是”整段覆盖下层”,而是在其骨骼遮罩范围内覆盖,范围外保留下层。一个层的输出再”完整”,也只在其遮罩范围内生效。
这套”分层 + 覆盖/叠加 + 骨骼遮罩”的机制,是本文所有内容的基础。下面几只怪,都是它的不同用法。
顺带给出一个量化结果:实测中,单只怪约 97% 的动画只归属于一个层。移动动画只在移动层,武器叠加只在武器层,受击只在受击层——职责切分极其干净,几乎不跨层复用。这是”分层合成”设计的必然:每个动画只承担单一职责,组合的工作交由运行时的分层合成完成,而非预先烘焙进单个动画。正是”单一职责 + 运行时组合”,让有限的动画素材撑起近乎无限的姿态空间(姿态 × 动作 × 武器 × 反应)。
二、近半数”动画”无法独立播放:混合空间
建立了分层的概念,再看第二个更反直觉的事实。
标准步兵 Conscript 在工程中落地了 339 个动画资产。直觉上会说”它有 339 个动画”。但这个说法会误导——因为其中相当一部分,并非可独立播放的动画剪辑。
按”每个资产的实际用途”划分,这 339 个是两类本质不同的对象:
- 动画剪辑(Animation Clip):135 个 —— 可由 AI 事件独立触发的完整动作。开火、换弹、死亡、受击,一次触发、一次播完。这是”离散”的。
- 混合采样(Blend Sample):202 个 —— 不独立播放,仅作为”采样”被混合空间引用。
第二类是理解现代角色动画的关键,需要讲透。它属于一个称为混合空间(Blend Space)的机制。
移动不是一个剪辑,是一组采样的实时插值
设想单位需要移动。最朴素的做法是制作一个”移动”剪辑循环播放。但真实单位要能朝任意方向、以任意速度移动——向前、斜向、侧移、后退,疾行、缓行。若为每种方向速度都制作一个剪辑,组合会爆炸。
混合空间的做法是:制作若干”极点”采样——如”向前移动””向左移动””向右移动””疾行””缓行””静止”,将它们注册到一个移动混合空间中。运行时,系统读取单位当前的移动方向与速度作为混合参数(Blend Parameter),对这些采样做加权插值(Weighted Interpolation),算出当前帧的姿态。
单位向左前方以中速移动时,混合空间可能取”向前 60% + 向左 30% + 缓行的一定权重”插值而得——这个姿态,不对应任何单一采样,它是运行时插值生成的。
所以那 202 个”混合采样”,正是这些极点。它们本身不是面向玩家的成品,仅是混合空间的输入。瞄准同理:上、下、左、右若干采样注册到瞄准混合空间,按瞄准角度插值出精确的枪口朝向。
实测这只 Conscript 有 41 个混合空间,共引用 302 个采样。移动、疾行、警戒移动、瞄准、持械待机——这些”连续可变”的动作,全部由混合空间运行时插值;仅开火、换弹、投掷、死亡这类”离散事件”,才使用一次性的动画剪辑。

为何这个区分至关重要
离散的动画剪辑 + 连续的混合空间,是现代 3A 角色动画中较为典型的一种结构。 一者”事件触发、一次播完”,一者”参数驱动、逐帧插值”。二者的实现、数据结构与驱动逻辑截然不同。(需说明:动画系统的实现因引擎而异——UE 的 AnimGraph、各家自研管线可能各有做法;这里描述的是本样本呈现出的、也颇具代表性的一种。)
若将二者混为一谈去统计”动画总数”,数字会虚高约一倍——看似 339 个动画,可独立触发的剪辑仅 135 个,其余 202 个是混合采样。一个角色”有多少动画”,若不区分这两类,答案就是错的。
这也解释了一个常见困惑:为何有些角色的动画目录里有数百个文件,游戏里可见的动作却并没有那么多?因为近半是混合采样——它们在目录中各占一个文件,但玩家永远不会单独看到任何一个,只会看到它们插值合成后的结果。
三、装备不同武器,动画复用吗?
前面讲的是单个动作的组织。再上升一层:同一只怪可装备多种武器,这些武器之间,动画是各做一套,还是可以复用?
答案是:大量复用,依靠三个维度的正交组合。
Conscript 可装备手枪、步枪、加农炮、火焰喷射器、狙击枪五类武器。若每类武器都制作一整套完整动画(移动、疾行、瞄准、待机、受击各一套),即五倍工作量。它没有这么做,而是将动画拆解为三个正交维度,组合而成:
下半身移动 × 上半身持械类别 × 武器类型
维度一:下半身移动。 移动、疾行、转身、警戒移动——这些与武器无关。无论手持何种武器,腿部动作一致。因此下半身仅一套移动动画,所有武器共享,完全复用。
维度二:上半身持械类别。 武器被归为”轻武器”与”重武器”两大类。同类武器(如手枪与步枪同属轻武器)的上半身持械、瞄准逻辑是共享的——通过骨骼遮罩,上半身叠加一套”轻武器持械”姿态。仅在切换到另一类(重武器)时才切换上半身逻辑。
维度三:武器类型。 到这一层才有”武器专属”的内容,且仅开火动作是专属的:加农炮开火后坐、步枪开火、火焰喷射器的独立瞄准循环,各自一套。除开火外,其余几乎都在前两个维度中复用。
理解了这三个维度,前面的数据便通了:为何”移动”在数据中关联到数十个混合采样?并非数十种不同的移动剪辑,而是”不同持械姿态 × 不同方向速度”的移动采样注册进混合空间——需要说明,下半身的腿部动作是所有武器共享的一套,数十个采样的差异主要在”上半身叠加何种持械姿态”以及”移动的方向与速度”。
这是一种相当经济的复用方式:连续运动(移动/瞄准/持械)交由混合空间与骨骼遮罩处理,武器差异仅落在少数几个离散的开火剪辑上。 一套下半身 + 两类上半身 + 每类武器若干开火,组合出”五类武器 × 全套动作”的表现,而实际制作量远小于”五套完整动画”。
这是可直接迁移到自有项目的思路:当一个角色需支持 N 种武器时,不应制作 N 套动画,而应找出正交、可复用的维度,仅在真正差异的环节(通常是开火)制作专属内容。

四、不同怪物之间,动画共享吗?
复用还可再上升一层:不是同一只怪的不同武器,而是不同怪物之间,动画共享吗?
这个维度最大,结论也最干脆,且分为截然不同的两档:
第一档,同一只怪的变体之间:100% 共享。 Conscript 有多个变体(更换外观、更换武器),本质仍是同一只怪。实测它们共享全部动画,无一例外。原因合理:骨架相同、行为相同,仅外观不同,动画自然直接复用。这一档近乎”零成本”——增加一个变体,动画成本接近于零。
第二档,不同种类的怪之间:几乎不共享。 这才是反直觉之处。全局统计所有敌人引用的动画,仅约 14% 被多于一只怪引用,且绝大多数是两只怪的偶合,并不存在”一个动画被十余只怪共用”的情况。
为何种类之间几乎不复用?因为每种怪的骨架不同、体型不同、行为不同——移动姿态都不一样,无法直接套用。举一个最说明问题的例子:同一阵营中,标准步兵 Conscript 为 67 根骨骼,精英军官 Commissar 为 112 根骨骼,骨架规模相差近一倍(军官体型更大、可动部件更多)。骨架都无法对应,动画数据自然无法通用。

因此”动画复用”是严格分层的:变体级(换外观)近乎零成本,种类级(不同怪)几乎从零制作。 中间没有太多灰色地带。
这对成本估算很重要。制作一个新变体,动画成本接近于零;但制作一种全新的怪,即便同为人形、同样持械,动画基本要从头制作一套——因其骨架与体态独一无二。指望”这只怪与那只相近,动画复用一下”来节省成本,在种类级别上基本行不通。
五、基准样本:标准步兵 Conscript 的完整解剖
讲完四条通用机制,接下来用几只具体的怪,看这些机制在不同定位的角色上如何落地。先从最”标准”的一只——它是理解其它怪的基准。
Conscript 是教科书式的人形单位,将前述机制用得最规整。其数据画像:
- 339 个动画 = 135 剪辑 + 202 混合采样 + 2 兼用。
- 41 个混合空间,武器复用系统化(前面的三维正交,即从它身上拆出)。
- 17 个动画层——层数适中。
- 叠加层(additive)占比仅约 4%。
最后这个数字值得停留。它的动画中,仅约 4% 是叠加层(受击反馈之类),其余约 96% 为资源动画(美术制作的完整剪辑或混合采样)。为何叠加层占比如此之低?
因为它是 AI 单位,不需要玩家操作级的精细叠加。玩家单位需要瞄准时枪口随呼吸微动、开火时逐发累积后坐、受击时按受力方向精确晃动——这些精细的运行时叠加,是为”操作手感”服务的。AI 单位不需要手感,受击时叠加一层受击反馈即可,不必逐发精算后坐。因此其复杂度几乎全在”离散剪辑”与”移动混合空间”上,叠加层用得很省。
Conscript 代表了 3A 敌人动画的”合理基线”: 该有的都有(移动混合、多武器复用、各类受击死亡),但没有一处为”操作手感”过度投入。它的动画预算全部投向”AI 表现”,而非”操作反馈”。记住这个基线,下面两只怪都是它的”变奏”——一个走向极端,一个反向而行。

六、极端之一:飞行 BOSS Dragonroach 为何”招式最少,叠加最多”
第一只变奏,是飞行 BOSS Dragonroach。它的数据画像与 Conscript 处处相反,而每一处相反都有清晰成因。
- 仅 50 个动画(Conscript 339)——动作极少。
- 核心动作仅数个:喷吐、滑翔、受击、死亡。
- 但叠加层占比约 36%(Conscript 约 4%)——高出近十倍。
“招式最少”与”叠加最多”集于一身,乍看矛盾,实为同一成因的两面:它在飞行。
先说”招式少”。BOSS 属”数个大招”型设计——不需要步兵那样丰富的战术动作(巡逻、掩体、多武器切换),它只是在空中盘旋、俯冲喷吐、承受伤害。行为模式精简,离散剪辑自然少。
再说”叠加多”,这是关键。飞行中的单位,其主体动作(如”滑翔巡航”)是一个持续循环。但飞行并非僵直——它需要随气流摆动翼面、随转向倾斜机体、受击时在空中晃动。这些姿态微调,能否制作成完整剪辑去覆盖主体动作?
不能。一旦覆盖,便打断了飞行的连续性——不能在”滑翔”与”受气流扰动的滑翔”之间硬切,那会产生姿态跳变。这些微调必须叠加:在飞行主体之上,实时叠加一个”翼面摆动””机体倾斜””晃动”的增量,主体飞行完整保留。
因此飞行怪对叠加层的依赖,与其运动形态高度相关。地面步兵立于地面,受击叠加一下无妨;飞行怪任何时刻都在执行一个连续的空中动作,大量扰动更适合叠加、而非覆盖。约 36% 的叠加层占比,与”连续飞行”这一形态相互印证。
由此可提炼一条更一般的规律:一个单位的运动形态越”连续、不可打断”,其对叠加层的依赖越高。 站桩单位依靠覆盖即可,飞行/游泳/骑乘这类全程连续运动的单位,叠加占比必然偏高。反之,观察一只怪的叠加层占比,大致可推断其运动形态的”连续程度”。
顺带一提,同为”大体型”的地面巨兽(如需蓄力冲撞的 Charger),走的是另一条路:它将复杂度置于”离散的冲锋序列”——蓄力→加速→高速循环→撞击收尾,是一串可组合的状态,叠加层占比中等(约 28%,主要用于四足单位适应复杂地形的坡度调整)。飞行怪靠叠加、Charger 靠状态序列,同为”大怪”,复杂度落点完全不同。

七、极端之二:层少而动画多的”倒挂”说明了什么
第二只变奏更反常——它挑战的不是”动画多少”,而是”动画数量”与”状态机复杂度”是否等价。
这是被感染的人形 Corrupted(原为人类士兵,被某种力量感染为敌)。其数据画像中有一处刺眼的矛盾:
- 263 个动画——全部怪中最多。
- 却仅有 6 个动画层——全部怪中最少之一。
对比才知其反常:飞行 BOSS Dragonroach 为 12 层 / 50 动画,标准步兵 Conscript 为 17 层 / 339 动画。而 Corrupted,层数最少,动画却最多。层数与动画数,在它身上彻底倒挂。
为何?答案藏在它的来历:它是”被感染的人类士兵”。
这意味着它继承了人类士兵那一整套丰富的动画资产——人类可使用多种武器(手枪、步枪、火焰喷射器)、有五种不同的部位死亡(胸、头、左腿、右腿、腹部各一套死亡动画)、有多种迟疑踌躇动作。这些原是为”人类角色”制作的精细内容,被感染后原样保留。因此其动画资产极其丰富——263 个,继承自人类。
但它现在是敌人。作为 AI 控制的杂兵,其行为逻辑被大幅简化:不再需要玩家单位那样数十层的精细控制(瞄准叠加、武器手感、姿态微调一概不需),它只需在被感染后向目标发起攻击。因此其状态机极简——6 层即足以驱动。
于是产生了这个倒挂:“丰富的动画资产” + “简单的状态机” = 层少而动画多。
这个案例点破一个易犯的错误:“动画数量”不等于”动画系统复杂度”。 一只怪拥有数百个动画,不代表其状态机复杂;它可能只是继承了大量现成资产,而实际驱动逻辑很简单。反之,玩家单位状态机之复杂,也不只因动画多,更因那套分层叠加的驱动逻辑本身精密。
评估一个角色的动画系统,须分开看两件事:资产层(有多少动画素材)与逻辑层(状态机如何组织、如何驱动)。Corrupted 是资产极丰富、逻辑极简单;而精心设计的玩家单位是资产丰富、逻辑亦精密。二者是不同的东西,不能以”动画数量”一个指标概而论之。
(补一处实测的诚实:Corrupted 的动画命名覆盖率仅约 49%——近半为纯哈希、无可读名。因此对它的分类比其它怪更依赖”按结构推断”,精度须打折扣。逆向黑盒即是如此,有的角色命名完整,有的一片哈希,能坐实到哪一步便说到哪一步。)


八、设计取向:单体做深,种类做广
将前述观察收拢,可提炼出一条贯穿始终的设计取向。它不是某只怪的细节,而是整个动画系统在”成本投向何处”上的根本权衡。
玩家单位:单体做深。 一个角色,海量动画,数十个动画层,各类武器均做混合空间,叠加层用到极致。所有投入指向一个目标——操作手感。玩家会长时间注视自身角色,每一次瞄准的枪口微动、每一发子弹的后坐累积、每一次受击的方向感,都需精确。为此,不惜在单个角色上堆叠最多的动画与最复杂的逻辑。
怪物:种类做广。 数十种怪,每种独立一套动画,跨种类几乎不复用。单只怪的动画逻辑远比玩家单位简单(层数更少、叠加更省),但种类要多、风格要杂——步兵、冲锋兽、飞行 BOSS、精英军官、感染体……每一种都需有辨识度、有自身的战斗节奏。投入方向不是”单只做多精细”,而是”多样性与 AI 表现”。
这两种取向,恰好对应玩家单位与怪物在游戏中扮演的角色:
| | 玩家单位 | 怪物 |
|—|—|—|
| 投入方向 | 操作手感(单体做深) | 多样性 + AI 表现(种类做广) |
| 单体动画量 | 极大(数千) | 中小(数十至数百) |
| 动画层数 | 最多(约 31) | 较少(6–17) |
| 叠加层占比 | 高(精细叠加) | 普遍偏低,飞行/连续运动怪例外 |
| 跨个体复用 | 不适用 | 变体 100%,种类几乎 0 |

还有一条藏于细节、更反直觉的规律:体型越大的怪,动画层数反而越少。 飞行 BOSS、巨型泰坦这类大体型单位,招式都不多、层数都不高。其复杂度并未消失,而是转移了——飞行怪转移至”叠加层”(以 additive 处理连续飞行的扰动),巨型泰坦转移至”身体部件”(将每条腿、每块甲片做成独立的可破坏部件,各自一套叠加逻辑)。大怪的复杂度不在”招式数”,而在别处。
一个 3A 的怪物动画系统,更像是在这样一张”成本分配表”上做权衡:哪个角色值得做深,哪些角色需要做广;哪种运动形态更适合叠加,哪种依靠覆盖即可;哪一档复用近乎零成本,哪一档须从零。这些权衡叠加起来,构成的就不只是”美术制作了一批动画”,而更接近一套关于如何以有限的动画预算换取尽可能大的表现力的工程取舍。
九、AI 协作复盘
按本系列惯例,这一节不谈动画,而谈这次分析中人与 AI 如何协作——诚实记录人机协作的真实摩擦,是本系列区别于普通技术博客之处。
AI 承担了什么。 这次的重活是”将六个角色的状态机逐个解析、按十余个维度交叉统计、产出一批分析图”。遍历数百个状态、按类型归并、计算哈希交集、生成十余张数据图——这些机械但量大的工作,由 AI 承担,人不必手动清点数百个状态、逐个计算复用率。若无 AI,单是”摸清六个角色的状态机结构”就将耗费大量时间。但须强调:AI 在这里是加速工具, 不是可信的分析器——本文所有统计数字均经人工复核后方才采信, 下面两处翻车正说明这道复核不能省。
AI 在哪里出了错。 有两处印象深刻,且都很典型。
其一是统计口径。 AI 起初将”每个动作有数十个变体”表述为”数十种不同的动画剪辑”,并据此制图。是人追问了一句”这数十个变体究竟是什么、能否独立播放”,才逼出真相——它们其实是混合空间的采样,根本不独立播放。这个”剪辑 vs 混合采样”的区分,恰是本文第二节的核心,而它起初被 AI 含糊地混为一谈,数字直接虚高一倍。若不追问,该错误会一路带入结论。
其二是名称。 AI 依据怪物的结构特征”推测”了几个中文译名——甚至一度将一只中型单位误判为巨型泰坦。这些推测均为错误。名称属于外部事实,无法从数据结构推断,但 AI 倾向于”合理地编造一个”。后经联网查证 + 人工确认方得纠正,最终决定不确定的一律沿用内部英文标识、不强行翻译。
人如何补位。 关键在两点。其一,不接受含糊的数字:对”变体””版本”这类易混淆的措辞穷追不舍,厘清”到底是不是可独立播放的剪辑”这一口径——正是这一问,改写了整篇的数据基础。其二,对外部事实保持警惕:名称、来历这类信息,不让 AI 以其”推测”的答案蒙混,而是要求查证,不确定的宁可留白。
最终如何解决。 统计口径,靠回到原始数据、按”每个资产的唯一用途”重新统计(得出剪辑 135 / 混合采样 202),而非按”引用次数”统计(那会重复计数、虚高)。名称,靠承认”这是外部事实、AI 不应推测”,改用联网加人工确认,不确定的直接沿用内部标识。
这正是”AI 原生开发”的真实质感:AI 极大加速了”从黑盒到数据”的过程,但它给出的每一个反直觉结论,都值得人再追问一句”这个数字究竟从何而来”。 加速不等于免检——AI 负责将数百个状态快速摊开、算出一批数字,人负责在关键处按住它、追问口径、核对事实。二者缺一,要么慢,要么错。
*本文是”AI 原生游戏开发实践”系列的第七篇。前序:从资产复用到经验复用 · 把游戏角色模型逆向进引擎 · 场景逐区块重建。*