Elytra
Blog物理引擎

Active Ragdoll:从动画角色到物理角色

从动画与物理的根本矛盾出发,理解 Active Ragdoll 如何借助刚体、关节与反馈控制构造真正存在于物理世界中的角色,并系统讨论 PD Controller、平衡、行走、受击、抓取、Get Up 与 Unity 实现中的稳定性问题。

普通动画角色可以精确地奔跑、挥拳、攀爬和装弹,却往往并不真正“存在”于物理世界中。

手臂撞到墙,动画仍然希望它继续向前;一辆汽车撞上正在奔跑的 NPC,Animator 仍然可以若无其事地播放 Run;玩家抓住角色的手腕,角色骨骼与玩家施加的力之间也未必存在真正的动力学关系。

传统 Ragdoll 恰好走向另一个极端。

它拥有质量、惯性、碰撞和关节,能够自然地跌落、滚动和被击飞,却失去了主动行动的能力。它会遵守物理,却不会自己站立,更不会挥拳、奔跑和保持平衡。

Active Ragdoll(主动布娃娃)试图连接这两个世界。

它的核心思想不是“在动画和 Ragdoll 之间切换”,而是:

让一个真正参与物理模拟的身体,主动尝试完成动画或程序所表达的动作。

动画不再直接决定身体最终在哪里,而只是描述:

“我想成为这个姿势。”

身体通过关节产生类似肌肉的力矩去追逐目标姿态;与此同时,碰撞、重力、惯性、摩擦和外力仍然由物理解算器共同处理。

于是角色可以一边试图站立,一边真的被箱子推倒;一边尝试挥拳,一边因为手撞到墙而被迫弯曲手臂;一边努力奔跑,一边因为失去支撑而跌倒。

这使 Active Ragdoll 不只是一个动画技巧。

继续深入以后,它会把:

  • Skeleton Animation
  • Rigidbody
  • Joint
  • Constraint Solver
  • PD Controller
  • IK
  • Balance
  • Locomotion
  • Procedural Animation

甚至机器人控制中的一些基本思想连接到同一个问题上:

如何控制一个受到物理规律约束的身体?

本文以下 Unity API 以 Unity 6.0 的内置 3D Physics 文档为基准。Unity 的 GameObject 3D Physics 集成 NVIDIA PhysX,因此理解 PhysX 的 Joint 与 Constraint 模型也有助于理解 Unity 中 ConfigurableJoint 的行为。1


一、为什么需要 Active Ragdoll?

Active Ragdoll 最重要的设计动机,并不是“让角色倒下时更漂亮”。

它真正解决的是:

预先制作好的动画,与不可预测的物理世界之间存在根本矛盾。

1.1动画擅长描述动作,却不擅长解决现实

传统动画角色大致可以理解为:

Loading diagram…

Animator 根据当前状态计算每根骨骼的 Pose:

Idle
Walk
Run
Punch
Reload
Climb

然后这些 Pose 直接成为角色骨骼的最终结果。

这种模型有一个巨大的优点:

确定。

动画师制作什么,玩家就看到什么。

但它同时隐含了一个前提:

世界最好不要强烈反对这段动画。

假设角色正在挥拳。

动画告诉 Forearm:

接下来 100 ms 内继续向前旋转。

但此时前方突然出现一堵墙。

动画系统和物理世界给出了两个互相冲突的要求:

Animation:
手应该继续向前。

Physics:
这里已经有墙了。

如果 Animation 拥有绝对控制权,常见结果就是:

  • 手穿进墙中;
  • 身体穿过桌面;
  • 脚滑过地面;
  • 被重物撞击后仍继续播放原有动作;
  • 玩家无法真正通过物理作用改变角色姿态。

当然,我们可以不断在 Animator 外面增加补丁:

Foot IK
Hand IK
Hit Animation
Procedural Lean
Wall Detection
Animation Layer
Ragdoll Blend

这些技术都很有价值。

但随着交互自由度增加,会出现一个组合爆炸问题。

如果一个角色有:

  • 5 种当前动作;
  • 8 个撞击方向;
  • 4 种撞击强度;
  • 6 种环境形态;
  • 4 种身体状态;

哪怕粗暴相乘,也已经得到:

5×8×4×6×4=38405\times8\times4\times6\times4=3840

种组合。

真实沙盒、近战和 VR 游戏的状态空间远大于此。

这就是 Active Ragdoll 特别适合物理沙盒的原因:

不再试图为所有结果制作动画,而是定义产生结果的规则。

EA/Frostbite 在 GDC 2018 的 Driven Ragdoll 分享中就把这种能力描述为获得 emergent behaviors:角色既能够追踪动画,又能对实际交互做出动态反应,从而减少必须依靠大量固定动画覆盖所有情况的压力。2


1.2Passive Ragdoll 解决了物理,却失去了行动

普通 Ragdoll 则几乎是反过来的:

Loading diagram…

角色由若干刚体组成:

Pelvis
├─ Spine
│  ├─ Head
│  ├─ Left Arm
│  └─ Right Arm
├─ Left Leg
└─ Right Leg

每一块主要身体通常拥有:

Rigidbody
Collider
Joint

这时最终姿态由 Physics 决定。

角色终于拥有了:

  • 重量;
  • 惯性;
  • 碰撞;
  • 摩擦;
  • 关节限制;
  • 对外力的自然响应。

但它不会主动完成任何动作。

普通 Ragdoll 很擅长:

被世界作用。

却不擅长:

主动作用于世界。

Active Ragdoll 所增加的,就是这第二种能力。


1.3三种角色模型真正不同的是“谁拥有最终控制权”

可以把三种系统放到一起:

模型动画物理最终姿态由谁决定
Animation Character强弱 / 辅助Animation
Passive Ragdoll无主动控制强Physics
Active Ragdoll提供目标强Physics + Controller

Active Ragdoll 最重要的转变不是:

Animator + Rigidbody

而是:

Animation = Intent
Physics = Reality

动画描述意图。

物理决定现实。

这也是理解整篇文章最重要的心智模型。

Active Ragdoll 并不是想消灭动画,而是在重新定义动画的权力:

动画可以提出要求,但不再拥有无条件执行要求的能力。


二、Active Ragdoll 的核心架构:让身体追逐一个目标

一种最容易理解、也最常见的 Active Ragdoll 架构,是同时维护:

  • Target Skeleton
  • Physical Skeleton

它们看起来像两具重叠的人体,但职责完全不同。

2.1Target Skeleton:角色想做什么

Target Skeleton 通常仍然可以使用正常 Animator:

Animator
↓
Idle / Walk / Punch / Reload
↓
Target Pose

它不必承担主要的物理碰撞。

它只回答一个问题:

如果现实世界没有阻碍,我希望身体现在是什么姿势?

Target Pose 也不一定只能来自动画。

它可以继续被:

  • IK;
  • Foot Placement;
  • Aim;
  • Procedural Animation;
  • Balance Controller;
  • 玩家 Tracking;

进一步修改。

因此一个完整 Target Pipeline 可能是:

Loading diagram…

2.2Physical Skeleton:角色实际上做到了什么

另一套 Skeleton 则真正存在于物理世界:

Physical Bone
├─ Rigidbody
├─ Collider
└─ Joint

它受到:

Gravity
Collision
Friction
External Force
Joint Limit
Muscle Drive

共同影响。

最终渲染角色通常跟随这套 Physical Skeleton。

于是整个系统变成:

Loading diagram…

注意最后一条反馈:

Physical Skeleton → Controller

非常重要。

Controller 不只是知道:

目标在哪里?

还必须知道:

我现在在哪里?

只有这样才能计算误差。


2.3Active Ragdoll 本质上是闭环控制

我们拥有:

Target Pose\text{Target Pose}

和:

Current Physical Pose\text{Current Physical Pose}

控制器计算两者之间的误差,再产生 Force / Torque:

Loading diagram…

这就是典型的:

Closed-loop Control System——闭环控制系统。

如果 Physical Arm 因为撞墙而偏离 Target Arm:

Target Arm
     \
      \
       \

Wall █████

Physical Arm
     |
     |

误差增大。

Controller 就会尝试产生更大的恢复力矩。

但如果墙仍然挡在那里,Physics Solver 不会允许它简单穿过去。

于是最终姿态来自:

Muscle
+
Joint
+
Wall Contact
+
Friction
+
Inertia

之间的共同求解。

这就是为什么 Active Ragdoll 能够自然产生普通动画难以覆盖的结果。


2.4Active Ragdoll 不等于 Animation / Ragdoll Blend

这里必须区分另一个常见技术:

Animation Pose ─┐
                ├─ Blend → Final Pose
Ragdoll Pose ───┘

例如:

Pfinal=(1−w)Panim+wPragdollP_{\text{final}} = (1-w)P_{\text{anim}} + wP_{\text{ragdoll}}

这种方法非常适合:

  • 动画到死亡 Ragdoll 的平滑过渡;
  • 部分身体物理化;
  • Ragdoll Recovery。

但其核心仍然是:

混合两个已有的 Pose。

Active Ragdoll 则是:

Target Pose
↓
Controller
↓
Force / Torque
↓
Physics Solver
↓
Physical Pose

Target Pose 并不会直接成为最终 Pose。

业界并没有一个严格统一的 “Active Ragdoll” 标准。

Wolfire 在开发 Overgrowth 时把它描述为“physically simulated, but not totally passive”的角色;Human: Fall Flat 开发者使用过 “fully active ragdoll”;EA/Frostbite 则使用 “driven ragdoll”。342

它们实现细节不同,但共同思想都是:

让物理身体保留主动控制能力。


三、肌肉的本质:反馈控制、PD Controller 与 Joint Drive

做到最简单的 Active Ragdoll Demo 并不困难。

真正重要的是理解:

Joint 为什么能够“像肌肉一样”把身体拉向动画?

答案来自控制理论。

3.1从姿态误差产生力矩

先考虑一个只有单一旋转轴的关节。

当前角度:

θ\theta

目标角度:

θt\theta_t

当前角速度:

ω\omega

目标角速度:

ωt\omega_t

一个基础 PD Controller 可以写成:

τ=Kp(θt−θ)+Kd(ωt−ω)\tau = K_p(\theta_t-\theta) + K_d(\omega_t-\omega)

其中:

  • τ\tau:控制器输出的力矩;
  • KpK_p:Proportional Gain;
  • KdK_d:Derivative Gain。

如果目标角速度为 0:

τ=Kp(θt−θ)−Kdω\tau = K_p(\theta_t-\theta)-K_d\omega

可以把两部分直观理解为:

P:离目标越远,拉得越用力
D:移动得越快,越努力把它刹住

所以:

P 很像 Spring。

D 很像 Damper。

NVIDIA PhysX 对 D6 Joint Drive 的定义正是这种形式:Drive 是一个带 Force Limit 的阻尼弹簧,其基本关系写作 stiffness * positionError + damping * velocityError;PhysX 也支持把 Drive 配置为 Acceleration Drive。5


3.2为什么只有 Spring 会疯狂振荡

假设一只手臂需要从:

0°

旋转到:

90°

如果只有 Spring:

0° → 90° → 115° → 76° → 101° → ...

身体会不断越过目标。

Damping 的作用就是吸收这种速度:

Spring:
快回去!

Damper:
别冲那么快。

对于最简单的一自由度质量—弹簧系统,临界阻尼满足:

ccritical=2kmc_{\mathrm{critical}}=2\sqrt{km}

对于旋转系统,更合适的直觉是把质量换成对应轴上的转动惯量:

ccritical≈2kIc_{\mathrm{critical}}\approx2\sqrt{kI}

但一个完整 Ragdoll 显然远比单自由度系统复杂:

  • Joint 互相连接;
  • 惯性是三维张量;
  • 身体不断发生接触;
  • 多个 Constraint 同时作用;
  • Solver 只是有限次迭代求解。

所以这两个公式更适合作为理解 Spring 与 Damping 关系的直觉,而不是直接生成最终游戏参数的万能公式。


3.3为什么 Spring 越大并不一定越“强”

Active Ragdoll 调参最常见的路径之一是:

身体太软
↓
Spring × 10
↓
还是不够
↓
再 × 10
↓
角色起飞

这是因为 Joint Drive 并不是独立存在的。

实际系统是:

Stiffness
+ Damping
+ Maximum Force
+ Mass
+ Inertia
+ Time Step
+ Solver Iterations
+ Collision Constraints

共同作用。

Stiffness 越高,意味着:

Solver 必须在一次 Physics Step 内纠正更强烈的误差。

如果误差很大、时间步又很长,就可能要求身体瞬间产生极端速度变化。

结果并不是“更稳定”,反而可能是:

  • 高频振荡;
  • Joint Separation;
  • Collider 穿透;
  • Constraint Solver 无法收敛;
  • 整具身体突然获得巨大能量。

因此 Active Ragdoll 的第一条调参原则应该是:

不要孤立地调 Spring。


3.4三维旋转不能简单做减法

位置误差很好理解:

ep=xt−x\mathbf e_p = \mathbf x_t-\mathbf x

Rotation 则不能简单写:

target.eulerAngles - current.eulerAngles

因为:

1°

和:

359°

实际上只差:

2°

而不是 358°。

三维旋转还涉及:

  • Quaternion;
  • Local Space;
  • Parent Space;
  • Joint Space;
  • Swing / Twist。

概念上通常先得到 Quaternion Error:

qe=qtq−1q_e=q_tq^{-1}

然后从 qeq_e 得到旋转轴与角度,或者由物理引擎内部直接完成 Quaternion / Swing-Twist Drive。

这一点也是为什么:

Active Ragdoll 中最危险的问题往往不是 Spring,而是坐标空间。


3.5Unity 中 ConfigurableJoint 如何对应这些概念

Unity 6.0 的 ConfigurableJoint 提供了:

  • targetRotation
  • targetAngularVelocity
  • angularXDrive
  • angularYZDrive
  • slerpDrive

等接口,并允许在 X/YZ Drive 和 Slerp Drive 之间选择旋转驱动模式。JointDrive 则包含 positionSpring、positionDamper、maximumForce 与 useAcceleration。67

因此概念映射大致可以理解为:

控制理论Unity Joint
Target PosetargetRotation
Target Angular VelocitytargetAngularVelocity
KpK_ppositionSpring
KdK_dpositionDamper
Actuator LimitmaximumForce
Force / Acceleration ModeluseAcceleration

Slerp Drive 会整体驱动三个角自由度,而 X/YZ Drive 则更适合需要分别考虑不同旋转自由度的情况。PhysX 的 D6 Joint 同样区分 Swing/Twist 与 SLERP Angular Drive。5


3.6最容易踩的坑:targetRotation 不是 Animator Rotation 的简单复制

下面这样的代码非常诱人:

joint.targetRotation = targetBone.localRotation;

但通常不能直接成立。

因为至少存在三个不同空间:

Bone Local Space
↓
Joint Frame
↓
Connected Body / Constraint Space

ConfigurableJoint 的 axis 和 secondaryAxis 定义了 Joint 自己的参考方向。

因此实际实现通常需要保存:

  • Initial Bone Rotation;
  • Initial Joint Rotation;
  • Joint Axis;
  • Connected Body Orientation;

然后把 Animator Pose 转换到 Joint 所理解的坐标系。

如果角色出现:

  • 一进入 Play 就爆炸;
  • 手臂固定偏 90°;
  • 左右手旋转方向相反;
  • Twist 看起来完全错误;
  • Spring 调多大都不正常;

优先检查:

Joint Space、Axis、Bind Pose 与 Target Rotation 的转换。

不要先把 Solver Iteration 调到 50。


四、Active 之前,先造一具好的 Ragdoll

一个经常被忽略的事实是:

Active Ragdoll 的上限,很大程度由 Passive Ragdoll 的质量决定。

如果关闭所有 Muscle 后,角色本身就:

  • 自己振动;
  • 关节乱折;
  • Collider 不断互相推开;
  • 身体比例失真;
  • 质量分布极端;

那么 Active Controller 只是在一个错误的物理模型上不断施加更大的力。

4.1Physical Skeleton 是动画骨架的物理抽象,不是复制品

角色 Render Rig 可能拥有:

80 Bones
100 Bones
150 Bones

这并不意味着需要同样数量的 Rigidbody。

一个游戏角色常见的 Physical Skeleton 可能只抽象:

Pelvis
Spine
Chest
Head

UpperArm × 2
Forearm × 2
Hand × 2

Thigh × 2
Calf × 2
Foot × 2

原因是:

Simulation Model 不需要等于 Render Model。

手指有几十根骨骼,不代表它们都值得进入全身 Ragdoll Solver。

每增加一个 Dynamic Body,都意味着增加:

  • Constraint;
  • Collision Pair;
  • Solver Work;
  • 潜在的不稳定源。

EA/Frostbite 在 Driven Ragdoll 的工程分享中也专门讨论了降低 Ragdoll 复杂度以改善性能和输出质量的问题。2


4.2Collider 的目标不是完美贴合 Mesh

一个 Active Ragdoll 的 Collider 更应该表达:

身体参与物理交互时的大致体积。

因此常见组合反而很简单:

部位常见 Collider
HeadSphere / Capsule
Spine / ChestCapsule / Box
PelvisBox / Capsule
Upper ArmCapsule
ForearmCapsule
ThighCapsule
CalfCapsule
FootBox / Capsule

如果为了“更真实”给角色加大量复杂 Convex Collider,往往会增加:

  • 细碎 Contact;
  • 边缘卡住;
  • Self Collision;
  • Solver 负担。

Active Ragdoll 需要的不是最高几何精度,而是:

稳定、连续、与 Gameplay 相符的碰撞代理。


4.3Self Collision 是一个设计选择

假设 UpperArm 和 Chest 的 Collider 在 Bind Pose 中稍微重叠。

Joint 说:

UpperArm 应该保持连接。

Contact Solver 说:

两个 Collider 不允许重叠。

于是系统可能陷入:

Joint 拉回来
↓
Collision 推出去
↓
Joint 再拉回来
↓
Collision 再推

因此相邻身体部位常常应该忽略彼此碰撞,例如:

UpperArm ↔ Chest
Forearm ↔ UpperArm
Thigh ↔ Pelvis
Calf ↔ Thigh

至于:

Hand ↔ Head
Arm ↔ Leg

这类非相邻 Self Collision 是否开启,就取决于玩法需求。

完整 Self Collision 并不天然意味着“更真实”。


4.4质量与惯性决定了身体是否像一个整体

如果所有 Bone 都设成:

mass = 1

会得到一具非常奇怪的人。

人体质量主要集中在:

  • 躯干;
  • 骨盆;
  • 大腿。

手和前臂则轻很多。

游戏并不需要严格复刻医学人体模型,但应该拥有合理的相对质量结构。

更重要的是:

相邻 Joint 两侧不要拥有极端的有效质量差。

PhysX 文档专门讨论了 Joint Mass / Inertia Scaling:让 Joint 两侧看到更接近的有效质量与惯性,可以帮助 Constraint Solver 更快收敛、减少“橡皮”或抽动,但这种 Scaling 本身是非物理的,会破坏严格的动量与能量关系。8

这很好地体现了游戏物理的重要原则:

视觉稳定性和严格物理真实性并不是同一个目标。

除了 mass,还不要忽视:

Center of Mass
Inertia Tensor

两个同样 5 kg 的物体,如果质量分布不同,对同样 Torque 的旋转响应也完全不同。


4.5Joint Limit 定义的不是动画范围,而是身体可行域

如果 Joint Limit 太宽:

角色会出现人体不可能的折叠。

如果太窄:

普通动画本身就可能不断撞击 Limit。

于是 Controller 一边说:

Follow Target!

Joint Limit 同时说:

You cannot rotate further.

两个 Constraint 长时间冲突,就会制造额外振荡。

所以 Joint Limit 的设计目标不是:

把角度限制得“医学上最真实”。

而是找一个同时满足:

Animation Coverage
Physical Plausibility
Solver Stability
Gameplay

的可行范围。


五、稳定性:为什么 Active Ragdoll 总是在抖?

当一个角色开始运行时,Physics Solver 看到的并不是“一个人”。

它看到的是一个巨大的 Constraint Problem:

15 Rigidbody
14 Joint
14 Joint Drive
多个 Joint Limit
Ground Contacts
Self Contacts
Friction
External Contacts
Grab Constraint

每个 Physics Step 中,这些条件都试图同时成立。

但实时物理引擎并不会无限精度地求出完美解析解。

它只能在有限 CPU 时间里:

通过有限迭代逼近一个足够好的解。

因此 Active Ragdoll 的许多“诡异 Bug”,其实是 Constraint System 没有在当前预算下得到稳定解。

5.1时间步是稳定性的第一层预算

Unity 的物理模拟使用固定时间步,Time.fixedDeltaTime 定义 Fixed Update 与默认 Physics Step 的游戏时间间隔。Unity 官方文档也明确建议物理模拟使用较小且一致的固定步长,因为随帧率变化的大时间步会降低准确性并更容易造成不稳定。9

例如:

Δt=0.02s\Delta t=0.02s

意味着:

50 Hz

而:

Δt=0.01s\Delta t=0.01s

意味着:

100 Hz

当 Controller 很硬时,更小的 Δt\Delta t 意味着:

每一步需要纠正的误差通常更小。

因此:

High Stiffness
+
Large Time Step

往往是危险组合。

但提高 Physics Frequency 同样意味着:

每秒需要做更多次碰撞与 Solver 工作。

所以这是典型的:

Stability ↔ CPU Cost

权衡。


5.2Animator 与 Physics 还必须处于正确的时间关系

Active Ragdoll 不是只有 Physics。

还存在:

Input
Animator
IK
Target Skeleton
Joint Drive
Physics
Render

如果 Physics 每次都在追:

上一次动画更新留下的 Target Pose,

就可能产生额外滞后和抖动。

Unity 6.0 的 Animator 可以选择 Normal 或 Fixed 更新模式;Fixed 模式在 Fixed Update Loop 中评估动画。10

这并不意味着:

Active Ragdoll 一定必须把 Animator 设置成 Fixed。

真正重要的是:

你必须明确 Animation Evaluation、Target Pose Capture 和 Physics Step 的先后关系。

概念上理想的数据流应该是:

Loading diagram…

而不是让这些阶段凭偶然顺序互相读取旧状态。


5.3Solver Iterations 是精度预算,不是修复按钮

Unity 的 Rigidbody.solverIterations 和 solverVelocityIterations 会影响 Joint 与 Contact 的求解精度;Unity 文档也明确指出,在 Jointed Rigidbody 或 Ragdoll 发生碰撞后表现过于松散时,提高 Velocity Iterations 可能有所帮助。11

对于这样的长约束链:

Pelvis
↓
Chest
↓
UpperArm
↓
Forearm
↓
Hand
↓
Grabbed Object

更高 Solver Budget 往往确实有帮助。

但它解决不了:

Wrong Joint Axis
Wrong Target Rotation
Collider Initial Penetration
Impossible Joint Limit
Extreme Drive

所以:

先修模型,再提高求解预算。


5.4Projection 是保险措施,不是 Controller

Unity 的 Joint Projection 可以在 Constraint 偏离过大时把 Joint 拉回合法区域。

但 Unity 文档明确指出:

Projection 不是物理过程,不保持动量,也不保证遵守碰撞几何;在 Joint 形成 Cycle 时,Projection 甚至可能无法执行。12

因此它应该被理解为:

Emergency Correction

而不是:

Primary Muscle System

如果 Projection 每一帧都在拯救角色:

说明底层设计大概率还有别的问题。


5.5Constraint Loop:抓取系统为什么特别容易炸

假设角色右手抓住一个箱子:

Chest
↓
UpperArm
↓
Forearm
↓
Hand
↓
Grab Joint
↓
Box

这只是 Constraint Chain。

如果两只手同时抓住一个方向盘:

Left Arm ── Left Hand ──┐
                        ↓
                  Steering Wheel
                        ↑
Right Arm ─ Right Hand ─┘

而两条手臂又通过 Chest 连接:

Constraint Loop 出现了。

现在系统同时要求:

  • 左手跟随动画;
  • 右手跟随动画;
  • 双手留在方向盘上;
  • 方向盘遵守自己的 Joint;
  • 胸口追踪 Target;
  • 所有 Collider 不穿透。

这些要求可能根本不存在完美同时满足的解。

解决方法往往不是:

把所有 Spring 调到 100000。

而是主动引入 Compliance——柔顺性:

  • Hand Drive 不必绝对精确;
  • Grab Joint 有 Force Limit;
  • Shoulder 可以承担一部分误差;
  • 物体过重时身体应该被拖动;
  • 力过大时 Grab 可以断开。

这是一条很重要的 Active Ragdoll 设计原则:

允许误差,往往比消灭误差更稳定。


5.6一个比“随机调参数”更有用的排查顺序

现象首先检查
Play 后立即爆炸Initial Penetration、Joint Space、Axis
肢体始终偏转Bind Rotation、Joint Frame
高频小抖动Stiffness、Damping、Time Step
Joint 被明显拉长Mass Ratio、Solver Budget
快速动作追不上Drive Strength、Angular Velocity Limit
撞墙后越来越暴躁Target Root 是否继续远离 Physical Root
双手抓物后爆炸Constraint Loop、Grab Compliance
倒地后疯狂抽搐Knockdown State 是否仍在全力追站立 Pose

Unity 的 Rigidbody.maxAngularVelocity 会限制 Rigidbody 的最大角速度,官方说明其目的之一就是避免高速旋转导致数值不稳定;因此“快速动画追不上”时它值得检查,但也不应简单无限提高。13


六、从“追 Pose”到“控制身体”:站立与行走

如果我们已经能够稳定追踪:

Idle Pose

是不是就意味着角色会站立?

答案是:

不一定。

这是 Active Ragdoll 从技术 Demo 走向真正 Character Controller 的分水岭。

Pose Control 和 Balance Control 是两个不同问题。

6.1一个站立 Pose 可能仍然在物理上必然倒下

角色由多个刚体组成。

整个系统的质心可以表示为:

c=∑imici∑imi\mathbf c = \frac{\sum_i m_i\mathbf c_i} {\sum_i m_i}

其中:

  • mim_i 是第 ii 个刚体质量;
  • ci\mathbf c_i 是其质心位置。

双脚与地面接触时,可以从 Foot Contact 构造一个支撑区域:

Support Polygon。

对于准静态情况,一个非常有用的判断是:

COM 的垂直投影是否位于支撑区域内?

        ● COM
        |
        |
        ↓

  [ Left Foot ][ Right Foot ]
  └──── Support Region ─────┘

如果 COM 投影远离支撑区域:

                         ●
                         |
                         ↓

  [ Left Foot ][ Right Foot ]

无论 Idle Animation 看起来多么像“站姿”,身体都很难仅靠原地保持。

Support Polygon、ZMP 等概念长期用于双足机器人平衡研究;但需要注意,COM 投影位于支撑区域主要是一个很有价值的静态/准静态直觉,并不能完整描述动态平衡。动态行走还涉及惯性、角动量、接触力以及 Zero-Moment Point 等条件。14


6.2为什么角色最终必须学会“迈一步”

假设角色被轻轻推了一下。

它可以通过:

  • Ankle;
  • Hip;
  • Spine;

调整姿态,把 COM 拉回来。

但如果扰动足够大:

Feet

[--------]

                    ● COM
                    → velocity

仅改变上半身姿势已经救不回来。

真正的人会改变:

支撑区域本身。

也就是:

迈一步。

于是系统从:

Pose Tracking

升级为:

Balance Control

再升级为:

Stepping Control

一个概念性的 Controller 可以是:

Loading diagram…

这里发生了一个非常重要的变化:

一开始:

Animation 决定 Pose。

现在:

Physics State 反过来修改 Animation / Target Pose。

这才是完整闭环。


6.3Walking 不是“播放 Walk 动画”

如果普通 Animator 播放 Walk:

动画往往已经假设:

Root 向前移动
+
脚按预定轨迹移动

但 Physical Foot 有真实的:

  • Contact;
  • Friction;
  • Velocity;
  • Mass。

于是可能出现:

Animation:
脚应该向后划。

Physics:
这只脚正在承担身体重量,应该抓住地面。

结果就是经典的:

滑冰。

因此物理步行通常必须区分:

Stance Foot

正在承担支撑的脚。

Swing Foot

正在移动到下一个落脚位置的脚。

Phase A:
Left = Stance
Right = Swing

Phase B:
Left = Swing
Right = Stance

这意味着真正的 Physical Locomotion 已经不只是 Animation Playback,而是在处理:

Gait
Foot Contact
Foot Target
Pelvis
Balance
Desired Velocity

之间的关系。


6.4IK 没有因为 Active Ragdoll 而失去意义

一个非常合理的 Pipeline 是:

Animation
↓
Foot / Hand IK
↓
Target Skeleton
↓
Active Ragdoll
↓
Physical Skeleton

IK 回答:

脚最好放在哪里?

Active Ragdoll 回答:

真实身体在当前物理环境下能做到多少?

两者不是竞争关系。

它们解决的是不同层次的问题。


6.5Root Motion 应该从“位移命令”变成“运动意图”

普通 Root Motion 隐含:

Animator Root Position
=
Character Position

但 Active Ragdoll 必须面对:

Animation:
向前 4 m/s。

Physics:
两米外是一堵墙。

如果直接应用 Root Motion:

Physical Character 最终仍会被 Transform 拖动。

如果完全忽略 Root Motion:

动画步态和世界运动又可能失去关系。

一种更符合 Active Ragdoll 思想的办法是把 Root Motion 解读为:

Desired Velocity

或者:

Desired Displacement

然后让 Locomotion Controller 尝试通过物理实现它。

再次回到那条核心原则:

Animation 描述意图,Physics 决定现实。


七、真正让 Active Ragdoll 有价值的行为:受击、倒地、抓取与恢复

如果 Active Ragdoll 最终只是:

用更昂贵的方法播放 Walk Animation,

那么它的价值非常有限。

它真正开始发光,是从外部世界能够不断改变角色开始。

7.1Hit Reaction:不要播放“被打”,让身体真的被打

传统 Hit Reaction 通常需要:

HitFront
HitBack
HitLeft
HitRight

Head
Chest
Arm
Leg

Light
Heavy

Active Ragdoll 则可以让 Collision / Impulse 本身成为动作的一部分:

Run Control
+
Impact
+
Balance
+
Muscle
+
Foot Contact

最终共同产生结果。

轻击:

身体晃动,然后恢复。

重击:

Spine 偏转,脚开始调整。

更强的攻击:

Balance 失败,进入 Knockdown。

这种反应不是从数据库里选择的一段固定 Pose,而是从当前状态中生成。

这正是 EA/Frostbite 所强调的 Driven Ragdoll 的价值之一。2


7.2Muscle 不应该只有 On / Off

最粗糙的设计通常是:

bool isRagdoll;

于是:

false = Active
true  = Passive

但更加自然的模型是:

s∈[0,1]s\in[0,1]

其中:

0 = Passive
1 = Fully Driven

进一步甚至可以:

Spine Strength
Arm Strength
Leg Strength
Neck Strength

全部独立变化。

例如胸口受到重击:

Spine
1.0 → 0.35 → 0.5 → 0.7 → 1.0

角色表现出来的就不是:

突然全身断电。

而是:

胸口一瞬间没有撑住,然后重新获得控制。

这也是为什么更成熟的 Active Ragdoll 更适合用:

Muscle State

而不是:

Ragdoll Switch

来思考。


7.3Knockdown 的关键是知道什么时候应该放弃平衡

一个 Character Controller 如果永远试图保持站立,会出现很荒谬的状态:

角色已经横着飞出去
+
双腿仍然全力追 Run Pose

因此需要判断:

什么时候当前姿态已经不可恢复?

可能参考:

Pelvis Height
Body Orientation
COM Error
Linear Velocity
Angular Velocity
Foot Contacts
Impact Magnitude

一旦进入 Falling / Knockdown:

可以主动改变 Muscle Configuration:

状态SpineArmLeg目的
Normal高中高高正常控制
Stagger中中中恢复平衡
Falling低中高低允许倒下、保护身体
Unconscious极低极低极低接近 Passive
Dead000Passive Ragdoll

这里的数值不重要。

真正重要的是:

不同状态可以拥有不同身体控制策略。


7.4Falling 也可以是主动行为

现实中的人开始跌倒后,并不会瞬间让所有肌肉归零。

可能会:

  • 伸手撑地;
  • 保护头部;
  • 收缩躯干;
  • 抓住栏杆;
  • 调整腿部。

于是 Falling 本身也可以拥有 Controller:

Leg Control ↓
Arm Protection ↑
Head Protection ↑
Grab Opportunity ↑

这时系统已经从:

Pose Driven Ragdoll

开始进入:

Physical Character Behavior。


7.5Get Up 为什么比倒下难得多

倒下很容易:

Muscle ↓
Gravity
↓
Fall

站起来则必须解决:

当前 Physical Pose 与 Get-Up Animation 根本不是从同一个姿态开始。

角色可能:

  • 仰卧;
  • 俯卧;
  • 侧躺;
  • 卡在墙边;
  • 一只腿搭在箱子上;
  • 一只手压在身体下面。

第一步通常是估计当前身体朝向:

Supine
Prone
Side

然后选择相应 Get-Up Strategy。

但最重要的步骤不是选 Animation Clip。

而是:

先把 Target Skeleton 对齐 Physical Body。

如果 Physical Pelvis 在 A:

A

而 Animator Get-Up Root 在 B:

                     B

直接播放动画意味着 Joint Controller 会试图:

瞬间把身体拖到 B。

正确流程通常更接近:

Loading diagram…

Wolfire 在 Overgrowth 的开发记录里就公开记录过从 Ragdoll 站起、Ragdoll Recovery,以及 Active Ragdoll 在狭窄空间中的改进。15


7.6Grab 与 Climb 会把角色变成一个更大的物理系统

角色没有抓东西时:

Body

是一套内部 Constraint Graph。

当手抓住环境:

Body
↓
Hand
↓
World

角色突然和世界成为了同一套 Constraint System。

攀爬尤其明显:

Left Hand Anchor
Right Hand Anchor
Body Weight
Leg Contacts

此时手不只是:

跟随 Hand Target。

它还在:

承担整具身体的重量。

因此一个成熟 Grab System 往往需要根据:

  • Object Mass;
  • Hand Force;
  • Shoulder Load;
  • Body Position;

动态调整控制策略。


7.7VR 把“控制权冲突”推到了极致

VR 手柄 Tracking 给出:

我的真实手现在必须在这里。

Physics 却可能说:

那个位置在墙后面。

于是产生:

Tracked Hand →→→→

            █ Wall

Physical Hand ──|

如果 Tracking 绝对胜利:

手穿墙。

如果 Physics 绝对胜利:

虚拟手和真实手严重分离。

所以 VR Physical Character 的问题,本质上仍然是本文一直讨论的问题:

谁拥有多少控制权?

只不过这次第三方不是 Animator,而是玩家真实身体。


八、从 Active Ragdoll 到 Physical Character System

真正成熟的 Active Ragdoll 最终通常不会只是:

ActiveRagdoll.cs

因为“追踪 Pose”只是整个 Physical Character 的底层能力。

8.1一个可维护的系统应该分层

可以把系统划分成:

Loading diagram…

这里:

ActiveRagdollController

只负责:

Target Pose
→
Joint Target / Muscle Drive

BalanceController

负责:

COM
Foot Contact
Lean
Recovery
Stepping

LocomotionController

负责:

Desired Velocity
Gait
Foot Target
Pelvis Motion

HitReaction

负责:

Impact
→
Local Muscle Change
→
Stagger / Knockdown

PhysicalState

负责:

Normal
Stagger
Falling
KnockedDown
GettingUp
Unconscious
Dead

Grab / Climb

负责外部 Constraint。

这能避免最后出现一个:

ActiveRagdoll.cs
9000 lines

同时处理走路、受击、VR、方向盘和死亡。


8.2几个典型游戏其实代表了不同的设计目标

Active Ragdoll 没有唯一正确答案。

不同游戏只是选择了不同的:

Physics Freedom
↔
Control Precision

比例。

8.2.1Human: Fall Flat:把“不精确”变成玩法

Human: Fall Flat 的开发者曾公开说明:

Gang Beasts 和 Octodad 让他意识到 Fully Active Ragdoll 可以成为完整的 3D 角色系统,而不只是 FPS 中角色死亡后的效果;而 Overgrowth 关于 Procedural Animation 的资料则帮助其开始早期实验。4

Human: Fall Flat 的高明之处并不是消灭:

  • 摇晃;
  • 抓不准;
  • 身体迟钝;
  • 控制误差。

而是把这些特性直接设计成 Gameplay。

技术“缺陷”变成了游戏规则。


8.2.2Overgrowth:从 Ragdoll 走向 Physical Combat

Wolfire 在 2009 年开发 Overgrowth 时就明确写到,他们开始研究:

physically simulated, but not totally passive

的 Active Ragdoll。3

后续开发日志又不断出现:

  • active ragdoll;
  • ragdoll recovery;
  • leg IK;
  • climbing;
  • standing up from ragdoll;

这些内容。

它代表了另一条路线:

Active Ragdoll 不只是搞笑物理,而可以服务于战斗、跑酷和动态身体反馈。


8.2.3EA / Frostbite:Driven Ragdoll 作为规模化动画系统的一部分

Frostbite 的方案很值得注意,因为它不是一个“物理玩具游戏”。

GDC 2018 的分享直接讨论了:

  • Animation Following;
  • Interaction Response;
  • Emergent Behavior;
  • Performance;
  • Bad Pose Reduction;
  • Feedback into Animation;
  • Networking;

这说明在大型商业角色系统中,Driven Ragdoll 真正的问题早已不是:

Joint 怎么转?

而是:

怎样让 Physical Character 与整个 Animation Pipeline 共存?2


8.2.4GTA IV / Euphoria:从“追 Pose”继续走向“执行行为”

GTA IV 使用了 NaturalMotion 的 Euphoria。同期公开资料把 Euphoria 描述为一种基于 Dynamic Motion Synthesis 的实时角色动画系统,它模拟角色的 Motor Control、Muscles 和 Biomechanics,使角色能够根据实际情况动态生成运动。16

因此最好不要简单写:

Euphoria = Active Ragdoll

它更接近 Active Ragdoll 再向上一层发展的方向。

普通 Pose Driven Ragdoll 的上层命令是:

把手放到这里。

Behavior Driven Physical Character 的上层命令则可以逐渐抽象成:

Stay Standing
Protect Head
Reach Object
Recover Balance

然后下层 Controller 自己决定身体如何完成它。

因此 Physical Character 可以粗略理解为几个层次:

Loading diagram…

越向右:

上层描述“目的”。

而不是描述每根骨头下一帧应该在哪里。


九、真正困难的不是 Ragdoll,而是“权力分配”

做到最后,会发现 Active Ragdoll 所有技术问题都在反复回到同一个核心矛盾。

角色中至少有三个系统在表达自己的要求:

Gameplay:
玩家按 W,我要向前。

Animation:
当前应该播放 Run。

Physics:
前面是一堵墙。

三者都没有错。

真正需要设计的是:

谁拥有多少权力?

普通 Animation Character 更接近:

Gameplay > Animation >>> Physics

Passive Ragdoll:

Physics >>> Everything

Active Ragdoll:

Gameplay
   ↕
Animation
   ↕
Physics

而所谓:

  • 手感;
  • 重量感;
  • 响应速度;
  • 物理真实性;
  • 稳定性;

很大程度上都是这套权力结构的结果。


9.1“物理越多越好”是一个危险目标

如果 Physics 权力过高:

角色可能很有重量感,却:

  • 很难控制;
  • 响应迟钝;
  • 经常跌倒;
  • 无法可靠完成 Gameplay Action。

如果 Controller 权力过高:

角色非常精准,却:

  • 像普通动画角色;
  • 外力没有存在感;
  • 撞击缺少重量;
  • Physical Interaction 变成视觉装饰。

所以真正成熟的 Physical Character 几乎必然是:

Hybrid System。

它会在不同场景下主动改变控制权。

例如:

普通移动:
Gameplay / Animation 权力高

轻微受击:
Physics 权力增加

Knockdown:
Physics 权力显著增加

Get Up:
Animation / Controller 逐渐重新接管

VR Hand Contact:
Tracking 与 Physics 协商

这比追求某个固定的:

“80% Physics”

有意义得多。


十、从 Demo 到可用系统:推荐实现路线

第一次实现 Active Ragdoll 时,最危险的目标就是:

一上来做 Euphoria。

因为这会同时引入:

Rigid Body Physics
Joint Solver
PD Control
Animation
IK
Balance
Walking
Grab
Get Up
Procedural Behavior

任何一层错误都会表现成:

“角色好像就是很怪。”

更可靠的方法是逐层建立能力。

10.1Phase 1:Passive Ragdoll

只做:

  • Rigidbody;
  • Collider;
  • Joint;
  • Joint Limit;
  • Mass Distribution;
  • Self Collision。

此时关闭所有主动 Drive。

目标不是好看,而是:

Ragdoll 本身不会无缘无故爆炸。

10.2Phase 2:Static Pose Tracking

增加 Target Skeleton 和 Joint Drive。

先只追一个静态 Pose:

T-Pose
↓
Idle Pose

解决:

  • Joint Space;
  • Bind Rotation;
  • Stiffness;
  • Damping。

不要碰 Walking。

10.3Phase 3:Animation Following

让普通 Animator 驱动 Target Skeleton。

开始测试:

Idle
Simple Gesture
Slow Walk

同时解决 Target Root 与 Physical Root 的关系。

10.4Phase 4:Muscle System

把:

bool isRagdoll

升级成:

Per-Bone Muscle Strength

支持:

  • Partial Ragdoll;
  • Local Hit;
  • Stun;
  • Falling。

10.5Phase 5:Hit、Knockdown 与 Recovery

让外部 Impulse 真正改变身体。

建立:

Normal
→ Stagger
→ Falling
→ KnockedDown
→ GettingUp

完整状态环。

到这里,一个 Active Ragdoll 已经具有非常明显的游戏价值。

10.6Phase 6:Locomotion

再开始处理:

  • Foot Contact;
  • Foot IK;
  • Stance / Swing;
  • Root Motion;
  • Desired Velocity。

此时你会第一次真正遇到:

Pose Tracking 并不等于 Walking。

10.7Phase 7:Balance 与 Stepping

计算:

  • COM;
  • Support Region;
  • Body Velocity;
  • Fall Prediction。

让系统能够主动决定什么时候改变 Foot Target。

这一步开始真正进入 Physical Character Controller。

10.8Phase 8:Grab、Climb、Vehicle 与 VR

最后处理复杂 Constraint:

Two-Hand Grab
Climbing
Steering Wheel
Seat
Tracked Hand
Tracked Head

这些问题建立在前面的身体控制已经足够稳定之后,才值得解决。


十一、什么时候应该用 Active Ragdoll?

Active Ragdoll 特别适合:

  • Physics Sandbox;
  • VR;
  • 近战;
  • 抓取与攀爬;
  • 高自由度环境交互;
  • Destruction;
  • Vehicle Interaction;
  • Emergent Gameplay。

因为这些游戏真正的问题都是:

世界状态无法被提前穷举。

但如果游戏要求的是:

  • 极低输入延迟;
  • 高度精确;
  • 动作结果严格可预测;
  • 竞技公平性;
  • 很少发生复杂身体交互;

那么完整 Active Ragdoll 未必值得。

一个:

Character Controller
+
Animation
+
IK
+
Procedural Reaction
+
Partial Ragdoll

可能更简单、更稳定,而且更符合游戏目标。

Active Ragdoll 并不是 Animator 的“升级版”。

它只是选择了另一个问题:

当角色必须真正成为物理世界的一部分时,如何仍然让他拥有行动能力?


十二、总结:动画描述意图,物理决定现实

如果只记住一个模型,可以记住:

Traditional Animation

Animation
↓
Final Pose
Passive Ragdoll

Physics
↓
Final Pose

而 Active Ragdoll 是:

Animation / AI / IK
↓
Target Pose
↓
Pose Error
↓
Muscle Controller
↓
Force / Torque
↓
Physics Solver
↓
Physical Pose
     ↑
     └──── Feedback

从这里,几乎整套系统都可以自然推导出来。

因为有 Pose Error,所以需要 PD Controller。

因为 Controller 输出 Force / Torque,所以需要考虑 Mass 和 Inertia。

因为身体由多个 Joint 连接,所以需要 Constraint Solver。

因为 Solver 只有有限预算,所以会出现 Time Step、Iterations 和稳定性问题。

因为一个站姿 Pose 并不保证不倒,所以需要 Balance。

因为 Balance 最终无法只靠扭动身体恢复,所以需要 Stepping。

因为脚真的接触地面,所以 Walking 必须考虑 Stance 与 Swing。

因为身体真的受到外力,所以 Hit Reaction 可以自然涌现。

因为角色可能真的倒下,所以必须解决 Get Up。

因为手真的抓住物体,所以会形成新的 Constraint Graph。

继续向上抽象以后,系统甚至会从:

“把身体变成这个 Pose”

走向:

“让身体完成这个行为”。

于是一个看似属于游戏动画的问题,最终连接到了机器人学里的同一个基本问题:

如何控制一个受到物理规律约束的多刚体系统?

区别在于,机器人不能作弊。

游戏可以。

我们可以:

  • 调整质量;
  • 修改惯性;
  • 提高摩擦;
  • 添加虚拟 Torque;
  • 偷偷修正 COM;
  • 改变 Muscle Strength;
  • 使用 IK;
  • 使用 Animation;
  • 必要时允许非物理 Correction。

这不是缺点。

恰恰相反,这是游戏角色设计最大的自由。

真正的目标从来不是:

构造一个最严格的人体动力学模拟器。

而是:

构造一个足够服从物理,因此能够产生可信而丰富的交互;又足够服从游戏设计,因此仍然稳定、响应迅速并且好玩的角色。

这才是 Active Ragdoll 最核心的设计问题。

也是它真正迷人的地方。

注释

  1. Unity Documentation,Physics system / Built-in 3D Physics(Unity 6.0)。Unity 官方说明面向 GameObject 的内置 3D Physics 集成 NVIDIA PhysX,用于 Rigidbody、Collider、Joint 和 Ragdoll 等系统。 ↩

  2. Jalpesh Sachania / EA Frostbite,Physics Driven Ragdolls and Animation at EA: From Sports to Star Wars,GDC 2018。该分享讨论 Driven Ragdoll 的动画追踪、交互响应、涌现行为、性能、异常 Pose、动画反馈与网络同步问题。 ↩ ↩2 ↩3 ↩4 ↩5

  3. David Rosen / Wolfire Games,Ragdoll physics - part one,2009。Overgrowth 开发日志中把正在研究的 Active Ragdoll 描述为“physically simulated, but not totally passive”的角色。 ↩ ↩2

  4. No Brakes Games / Human: Fall Flat 开发者,Gang Beasts?,Steam Community,2016。开发者说明 Gang Beasts 与 Octodad 展示了 Fully Active Ragdoll 作为完整 3D Character System 的可能性,并提到 Overgrowth Procedural Animation 对早期实现探索的影响。这属于开发者公开社区发言,而非正式技术论文。 ↩ ↩2

  5. NVIDIA,PhysX SDK Documentation — Joints / PxD6Drive。PhysX 将 D6 Drive 定义为受 Force Limit 限制的阻尼弹簧,并给出 stiffness * positionError + damping * velocityError 的 PD 型关系;Angular Drive 支持 Swing/Twist 与 SLERP 模式。 ↩ ↩2

  6. Unity Documentation,ConfigurableJoint / ConfigurableJoint.targetRotation / ConfigurableJoint.slerpDrive(Unity 6.0)。官方 API 定义 targetRotation 为 Joint 的目标 Quaternion,并提供 X/YZ 与 Slerp 两类 Rotation Drive。 ↩

  7. Unity Documentation,JointDrive(Unity 6.0)。JointDrive 暴露 positionSpring、positionDamper、maximumForce 与 useAcceleration,分别用于目标恢复强度、阻尼、驱动力上限以及 Force/Acceleration Drive 选择。 ↩

  8. NVIDIA,PhysX SDK Documentation — Joints: Mass Scaling。官方文档说明使 Joint 两端具有更接近的有效质量和惯性有助于 Solver 收敛并减少 Joint 松软或抽动,但同时指出 Mass/Inertia Scaling 是非物理处理,可能破坏动量与能量关系。 ↩

  9. Unity Documentation,Fixed updates / Manually set physics simulation(Unity 6.0)。Unity 建议物理模拟使用固定且一致的时间步,并指出大的可变时间步可能造成更不稳定或不准确的模拟。 ↩

  10. Unity Documentation,AnimatorUpdateMode(Unity 6.0)。Animator 支持 Normal 与 Fixed 等更新方式;Fixed 模式在 FixedUpdate Loop 中进行动画评估。 ↩

  11. Unity Documentation,Rigidbody.solverIterations / Rigidbody.solverVelocityIterations(Unity 6.0)。官方说明这些属性影响 Rigidbody Joint 与 Collision Contact 的求解精度,提高迭代数可以改善部分 Joint/Ragdoll 碰撞后的误差,但会增加计算成本。 ↩

  12. Unity Documentation,ConfigurableJoint projectionMode / projectionDistance(Unity 6.0)。官方明确指出 Projection 用于在 Solver 无法满足 Constraint 时重新对齐 Joint,但它不是物理过程、不保持动量、不保证尊重碰撞几何,而且在形成 Joint Cycle 时可能无法 Projection。 ↩

  13. Unity Documentation,Rigidbody.maxAngularVelocity(Unity 6.0)。官方说明该属性限制 Rigidbody 的最大角速度,并指出这一限制用于避免高速旋转导致的数值不稳定。 ↩

  14. Miomir Vukobratović、Branislav Borovac,Zero-Moment Point — Thirty Five Years of Its Life,International Journal of Humanoid Robotics,2004;另参见后续 Humanoid Robotics 文献对 Support Polygon、ZMP 与动态平衡的讨论。这里引用这些概念用于解释 Active Ragdoll 的平衡直觉,并不意味着游戏角色必须实现完整 ZMP Controller。 ↩

  15. Wolfire Games 的 Overgrowth 开发日志,包括 Overgrowth Alpha 84、Overgrowth a126 video changelog 等。日志记录了 Leg IK、Ragdoll Recovery、从 Ragdoll 站起以及狭窄空间中的 Active Ragdoll 改进。 ↩

  16. NaturalMotion / Rockstar 的同期资料以及 Game Developer 对 Euphoria 的报道。GTA IV 确认使用 NaturalMotion Euphoria;公开资料将其描述为基于 Dynamic Motion Synthesis 的实时角色系统,通过 Motor Control、Muscles 与 Biomechanics Simulation 动态合成交互运动。因此本文将它视为比基础 Pose-Driven Active Ragdoll 更广义的 Physical Character / Behavioral Simulation 案例。 ↩

CONTINUE EXPLORING

沿着这篇文章继续

在地图中查看

On this page

一、为什么需要 Active Ragdoll?1.1动画擅长描述动作,却不擅长解决现实1.2Passive Ragdoll 解决了物理,却失去了行动1.3三种角色模型真正不同的是“谁拥有最终控制权”二、Active Ragdoll 的核心架构:让身体追逐一个目标2.1Target Skeleton:角色想做什么2.2Physical Skeleton:角色实际上做到了什么2.3Active Ragdoll 本质上是闭环控制2.4Active Ragdoll 不等于 Animation / Ragdoll Blend三、肌肉的本质:反馈控制、PD Controller 与 Joint Drive3.1从姿态误差产生力矩3.2为什么只有 Spring 会疯狂振荡3.3为什么 Spring 越大并不一定越“强”3.4三维旋转不能简单做减法3.5Unity 中 ConfigurableJoint 如何对应这些概念3.6最容易踩的坑:targetRotation 不是 Animator Rotation 的简单复制四、Active 之前,先造一具好的 Ragdoll4.1Physical Skeleton 是动画骨架的物理抽象,不是复制品4.2Collider 的目标不是完美贴合 Mesh4.3Self Collision 是一个设计选择4.4质量与惯性决定了身体是否像一个整体4.5Joint Limit 定义的不是动画范围,而是身体可行域五、稳定性:为什么 Active Ragdoll 总是在抖?5.1时间步是稳定性的第一层预算5.2Animator 与 Physics 还必须处于正确的时间关系5.3Solver Iterations 是精度预算,不是修复按钮5.4Projection 是保险措施,不是 Controller5.5Constraint Loop:抓取系统为什么特别容易炸5.6一个比“随机调参数”更有用的排查顺序六、从“追 Pose”到“控制身体”:站立与行走6.1一个站立 Pose 可能仍然在物理上必然倒下6.2为什么角色最终必须学会“迈一步”6.3Walking 不是“播放 Walk 动画”6.4IK 没有因为 Active Ragdoll 而失去意义6.5Root Motion 应该从“位移命令”变成“运动意图”七、真正让 Active Ragdoll 有价值的行为:受击、倒地、抓取与恢复7.1Hit Reaction:不要播放“被打”,让身体真的被打7.2Muscle 不应该只有 On / Off7.3Knockdown 的关键是知道什么时候应该放弃平衡7.4Falling 也可以是主动行为7.5Get Up 为什么比倒下难得多7.6Grab 与 Climb 会把角色变成一个更大的物理系统7.7VR 把“控制权冲突”推到了极致八、从 Active Ragdoll 到 Physical Character System8.1一个可维护的系统应该分层8.2几个典型游戏其实代表了不同的设计目标8.2.1Human: Fall Flat:把“不精确”变成玩法8.2.2Overgrowth:从 Ragdoll 走向 Physical Combat8.2.3EA / Frostbite:Driven Ragdoll 作为规模化动画系统的一部分8.2.4GTA IV / Euphoria:从“追 Pose”继续走向“执行行为”九、真正困难的不是 Ragdoll,而是“权力分配”9.1“物理越多越好”是一个危险目标十、从 Demo 到可用系统:推荐实现路线10.1Phase 1:Passive Ragdoll10.2Phase 2:Static Pose Tracking10.3Phase 3:Animation Following10.4Phase 4:Muscle System10.5Phase 5:Hit、Knockdown 与 Recovery10.6Phase 6:Locomotion10.7Phase 7:Balance 与 Stepping10.8Phase 8:Grab、Climb、Vehicle 与 VR十一、什么时候应该用 Active Ragdoll?十二、总结:动画描述意图,物理决定现实注释