战斗几何学:Hitbox、Hurtbox 与 Pushbox
在电子游戏的战斗系统中,玩家屏幕上看到的画面极少直接对应底层物理引擎的计算结果。具有数万个多边形面数、复杂布料摆动和独立手指关节的高精度角色模型,在实时物理计算中极其消耗资源。现代游戏引擎将视觉渲染与几何碰撞彻底解耦,在后台构建一套肉眼不可见的简易几何边界,用以判定攻击是否命中、角色是否承受伤害以及如何在空间中占据物理实体。
为了清晰管理战斗机制,游戏引擎通常将角色碰撞体积划分为三种独立的功能性几何体:
+-------------------------------------------------------------------------+
| 战斗碰撞三元组 |
+-------------------------------------------------------------------------+
| 1. HITBOX(攻击判定框 / 主动触发体积) |
| - 仅在攻击、法术或投掷物的有效判定帧内激活生成 |
| - 主动检测场景中与其相交的易伤目标 |
| - 触发伤害结算、受击硬直(Hitstop)及击退冲量 |
+-------------------------------------------------------------------------+
| 2. HURTBOX(受击判定框 / 被动易伤体积) |
| - 绑定至角色骨骼关键节点(头部、躯干、四肢) |
| - 随动作姿态变换实时刷新空间坐标与旋转矩阵 |
| - 被动接收体:当被外部 Hitbox 侵入或重叠时触发受击逻辑 |
+-------------------------------------------------------------------------+
| 3. PUSHBOX / 环境碰撞体(实体物理阻挡体积) |
| - 通常为垂直胶囊体、圆柱体或简化立方形 |
| - 负责解析与环境几何(地面、墙壁、斜坡、障碍)的接触阻挡 |
| - 防止角色彼此重叠或穿透地形边界 |
+-------------------------------------------------------------------------+
空间隔离的架构必然性
如果游戏将角色的所有交互绑定在一个统一的碰撞体上,战斗机制将瞬间失衡:
- 若直接使用环境碰撞胶囊体结算伤害,玩家伸出手臂或挥刀时的空隙将全部判定为空气挨打,造成极其荒谬的判定外溢。
- 若武器与角色实体物理共享阻挡判定,大剑在砍向敌人时会在触碰到对方外层物理包围盒时瞬间被弹开,无法顺畅穿过肉身造成挥砍伤害。
- 通过解耦 Hitbox(攻击体)、Hurtbox(受击体)和 Pushbox(阻挡体),引擎可以为不同通道设置独立的碰撞响应通道(Collision Response Channels),对特定通道产生重叠回调(Overlap),对其他通道则维持阻挡(Block)。
两阶段碰撞流水线:宽相(Broad Phase)与窄相(Narrow Phase)
在同时存在数十个角色、弹道法术和动态环境物体的大型动作场景中,若每一帧都让场景中的所有碰撞体两两进行几何相交检测,计算量将呈现 $O(N^2)$ 指数级膨胀。场景中若有 100 个可碰撞实体,朴素算法每帧需要执行:
$$\frac{100 \times 99}{2} = 4,950 \text{ 次成对交叉测试}$$
为了在 60Hz 甚至 144Hz 的物理刷新率下保持毫秒级的帧生成时间,主流物理引擎(如 PhysX、Chaos、Havok)均将空间碰撞查询严格划分为两个阶段:
[ 场景中所有动态与静态实体 ]
|
v
+-----------------------------------------------------------+
| 宽相阶段(Broad Phase):粗粒度空间划分 |
| - 统一使用轴对齐包围盒(AABB) |
| - 遍历层次包围盒(BVH)、八叉树或扫掠修剪算法 |
| - 高速剔除 95% - 99% 完全不可能接触的实体对 |
+-----------------------------------------------------------+
|
|(仅传递潜在重叠的候选对)
v
+-----------------------------------------------------------+
| 窄相阶段(Narrow Phase):高精度几何相交求解 |
| - 针对候选对测试具体图元(球体、胶囊体、有向包围盒 OBB) |
| - 运行分离轴定理(SAT)或 GJK 距离算法 |
| - 精确计算接触点坐标、法线方向与穿透深度 |
+-----------------------------------------------------------+
|
v
[ 分发游戏逻辑事件:扣除血量、施加击退力、播放受击特效 ]
1. 宽相阶段的空间加速划分
宽相阶段完全忽略角色复杂的肢体网格,而是将每个物体直接封装在一个**轴对齐包围盒(Axis-Aligned Bounding Box, AABB)**中。AABB 的边始终平行于世界坐标轴 $(X, Y, Z)$,其重叠判断仅需比对最小与最大标量值:
$$\text{Overlap} \iff (A_{\min}^x \le B_{\max}^x \land A_{\max}^x \ge B_{\min}^x) \land (A_{\min}^y \le B_{\max}^y \land A_{\max}^y \ge B_{\min}^y) \land (A_{\min}^z \le B_{\max}^z \land A_{\max}^z \ge B_{\min}^z)$$
借助层次包围盒(BVH)、**八叉树(Octree)或扫掠修剪(Sweep and Prune)**等空间数据结构,引擎将空间邻近的物体归纳到树状层级中。如果玩家挥刀动作的包围盒未与远处敌人群体的父节点包围盒产生交集,引擎在一个时钟周期内即可跳过数十个潜在实体的比对,将计算复杂度从 $O(N^2)$ 压缩至 $O(N \log N)$ 乃至近乎 $O(N)$。
2. 窄相阶段的高精度几何解算
通过宽相筛选出的重叠候选对,将送入窄相阶段进行精确的几何代数解算:
- 球体 vs 球体:三维中最快的碰撞测试,仅需比较球心距离平方与半径之和的平方 $(|C_1 - C_2|^2 \le (R_1 + R_2)^2)$。
- 胶囊体 vs 胶囊体:求解两条内部骨骼线段之间的最短欧氏距离,再与半径之和比对。由于人类肢体形态天然契合圆柱两端封盖半球的胶囊几何,胶囊体是角色肢体 Hurtbox 最主要的基准图元。
- 有向包围盒(OBB)与凸包(Convex Hull):采用**分离轴定理(Separating Axis Theorem, SAT)**或 GJK 算法(Gilbert-Johnson-Keerthi)。如果在两个凸体之间能找到一条投影不发生重叠的分离轴或分离超平面,则两者互不接触。
在动态战斗中,引擎坚决避免使用逐多边形三角形网格(Per-Polygon Mesh)进行打击判定。在角色复杂的骨骼蒙皮动画下,让两个数万面的变形网格实时计算三角形相交,会瞬间耗尽 CPU 物理线程,引发严重的卡顿掉帧。
离散碰撞与连续碰撞检测(CCD):高速穿模(Tunneling)成因
动作游戏中最常见的判定缺陷莫过于“穿模空击”(Tunneling,玩家常称之为“挥刀穿透”、“子弹穿人”)。穿模的本质是高初速物体在两个物理帧之间直接跨越了目标,导致物理系统未曾捕获到任何接触。
穿模的数学物理机制
绝大多数物理引擎默认运行离散碰撞检测(Discrete Collision Detection)。在离散模式下,物理系统仅在离散的时间步长 $t, t + \Delta t$ 处取样物体空间位置:
帧 N(时间 = t): 帧 N+1(时间 = t + dt):
[ 子弹 / 刀刃 ] --- 速度 v ---> [ 子弹 / 刀刃 ]
o o
(位于 x=10) (位于 x=60)
| 目标护盾 / 角色 |
| [x=30..35] |
当物体以速度 $v$ 高速位移时,单个物理步长内的位移量为:
$$\Delta x = v \cdot \Delta t$$
如果目标判定体积的厚度 $W_{\text{target}}$ 加上飞行物本身的碰撞直径 $D_{\text{proj}}$ 小于该单帧位移量:
$$W_{\text{target}} + D_{\text{proj}} < v \cdot \Delta t$$
在帧 $N$ 时,物体完全位于目标前方;在帧 $N+1$ 时,物体已经完全位移至目标后方。由于离散引擎只在时间切片瞬间比对空间几何重叠,在这两个测试时刻物体与目标均未重叠。子弹或刀尖就这样如同幽灵般“穿透”了目标,判定完全失效。
连续碰撞检测(CCD)的工程实现
为了防止极高初速的弹丸、飞掷长矛或快速挥动的武器尖端发生穿模,引擎引入了连续碰撞检测(Continuous Collision Detection, CCD),主要涵盖两种工程路线:
+----------------------------------------------------------------------------+
| CCD 实现机制 |
+----------------------------------------------------------------------------+
| 1. 扫掠式 CCD(Sweep-based CCD / 体积挤出) |
| - 将物体图元沿运动速度向量挤出为一个连续轨迹扫掠体(Swept Volume) |
| - 求解该扫掠体在连续时间区间 [0, dt] 内与静态或动态目标的代数交点 |
| - 算出精确的冲击时间(Time of Impact, TOI ∈ [0, 1])与接触点法线 |
| - 局限:计算开销极其昂贵,多物体互动时易导致物理线程过载 |
+----------------------------------------------------------------------------+
| 2. 推测式 CCD(Speculative CCD / 预测膨胀包围盒) |
| - 根据预期运动速度,在宽相阶段将物体的 AABB 包围盒向前膨胀延伸 |
| - 在发生实际物理接触前提前建立接触约束条件,限制其穿透速度 |
| - 优势:计算消耗远低于扫掠式求解,对 CPU 极为友好 |
| - 局限:物体突发变向时可能出现“空气撞墙”(Ghost Collision)误判 |
+----------------------------------------------------------------------------+
在快节奏射击游戏中,开发者通常彻底放弃让子弹作为带有物理实体的刚体飞行,而是改用射线投射(Line Trace / Raycast)。在武器开火瞬间,系统以枪口为起点、目标朝向为矢量直接投射一条数学线段,沿途立即捕捉穿过的 Hurtbox,以极低的系统开销实现绝对不穿模的即时命中(Hitscan)判定。
视觉模型与物理判定脱节的根源
玩家常常困惑于“明明砍中了模型却没有伤害”,或是“离敌人身体还有半米远就被击中”。这种体验断层源自视觉渲染与物理几何之间的固有矛盾。
1. 简易胶囊体与复杂人体外形的贴合差异
视觉模型具备逼真的肌肉起伏、铠甲护肩与外挂披风,而负责接收伤害的 Hurtbox 通常仅由若干挂载在骨骼上的胶囊体拼合而成。
开发团队在配置胶囊体时必须做出权衡:
- 收紧型 Hurtbox(小于视觉模型):保护边缘免受不合理判定侵扰,但会导致击中披风、铠甲尖刺或刀鞘边缘时出现“穿模却未命中”的视觉违和。
- 宽容型 Hurtbox(大于视觉模型):确保擦过身体的攻击必定能造成伤害,但玩家在近距离闪避时容易被明显的“空气刀”划伤。
2. 动画混合与根骨骼位移(Root Motion)的微步脱节
现代角色动作依赖复杂的动画混合树(Blend Tree)。当角色从蓄力攻击强行接入闪避翻滚时,GPU 顶点着色器在数百毫秒内平滑插值过渡两个动作的网格形变。
然而,Hurtbox 往往随骨骼插槽变换矩阵离散刷新。如果动作过渡曲线与底层物理位移速度不同步,或者根骨骼位移在网络或帧率波动时出现微小延迟,屏幕上渲染的视觉角色可能会短暂偏离真实的碰撞胶囊体。
3. 外扩判定(Disjoint Hitbox)与判定帧滞后(Linger Frames)
在动作与格斗游戏中,开发者经常特意设计“脱节判定”(Disjoint Hitbox)——攻击 Hitbox 的有效范围故意延伸超出武器刀刃前端;或者在武器挥砍动作已经收招的数帧内,依然保留伤害判定(滞后判定帧)。
这种非写实的设计往往是刻意为之:它能补偿人类神经反应延迟,确保空中下劈能稳定命中低矮受击面,并赋予重型武器十足的打击压制力。虽然从静止画面上看显得“判定崩坏”,但在动态操作中它能带来更爽快的交互反馈。
4. 纯装饰性特效(VFX)不具备物理实体
重武器挥舞时的耀眼刀光、火焰法术的拖尾粒子、枪口爆裂的火花均属于 GPU 渲染管线中的特效通道。特效贴图本身完全不包含任何碰撞信息。如果刀光延伸三米远而特效对应范围未单独挂载 Hitbox,仅用刀身本体攻击的目标在特效范围内自然不会受到任何伤害。
核心碰撞检测模式对比矩阵
下表系统梳理了主流游戏物理引擎中四种判定机制的技术特性与权衡取舍:
| 碰撞检测模式 | 计算资源开销 | 穿透静态地形风险 | 穿透动态角色风险 | 典型应用场景 | 关键权衡与失效缺陷 |
|---|---|---|---|---|---|
| 离散检测(Discrete) | 极低(单帧静态图元比对) | 高速时必然穿透 | 高速时必然穿透 | 普通角色行走跑动、场景大型建筑、低速怪物 | 帧率下降时穿模加剧;超薄障碍物易被直接穿透 |
| 扫掠式 CCD(Sweep-based) | 高(连续时空轨迹代数求解) | 完全消除 | 双方均开启时完全消除 | 高速冷兵器挥砍刃尖、掷矛投掷物、高速载具碰撞 | 多个高速物体同时碰撞时 CPU 计算暴增,引发卡顿 |
| 推测式 CCD(Speculative) | 中等(预先膨胀预测包围盒) | 大幅降低 | 大幅降低 | 角色布娃娃物理(Ragdoll)、散落物理碎片 | 轨迹突变时可能在接触前发生空气弹开(幽灵碰撞) |
| 射线投射(Line Trace / Raycast) | 低($O(1)$ 空间线段求交) | 路径上完全消除 | 路径上完全消除 | 枪械即时命中弹道、地面贴合吸附检测、视线判定 | 无三维物理体积;若穿过相邻胶囊体的微小缝隙可能漏检 |
引擎内置碰撞诊断与实机排查
无论是独立游戏开发者调试手感、Mod 创作者调整武器手感,还是竞技玩家定位判定疑虑,单纯依赖录像眼球判断极易产生误区。玩家与开发者可以通过引擎控制台直观呈现底层的真实几何碰撞。
1. 控制台几何可视化指令
虚幻引擎(Unreal Engine 4 / 5)
在开启控制台的测试构建或特定游戏中按下 ~ 键,输入以下指令调出底层碰撞网格:
show collision # 渲染当前视口内所有激活的静态与动态碰撞线框
show CollisionPawn # 过滤仅显示角色受击胶囊体(Pawn Hurtbox)
pxvis collision # 强制显示 PhysX / Chaos 底层物理线框
- 青色 / 绿色线框:代表常规简化物理碰撞体(胶囊体、球体、立方形)。
- 红色 / 紫色线框:代表当前帧处于激活状态的攻击判定形状(Trace Shape / Hitbox)。
Source / Source 2 引擎
在 Valve 旗下的 Source 系列引擎私人服务器中,可调出服务端追溯补偿判定框:
sv_showlagcompensation 1 # 绘制服务器端网络回滚后用于计算命中的实际判定盒
r_drawclipbrushes 1 # 绘制场景环境空气墙及阻挡笔刷(Clip Brushes)
2. 实机判定异常诊断排查流程
当遇到攻击似乎“莫名挥空”或“隔空挨打”时,可按以下三个步骤定位症结:
- 第一步:核查物理刷新率与瞬时帧率
- 检查游戏在交战瞬间是否发生了掉帧(如从 60 帧跌落至 25 帧)。离散物理系统的采样间隔 $\Delta t$ 成倍拉长,使武器尖端单帧位移直接超过敌人身形厚度,引发穿模。
- 第二步:比对骨骼插槽对齐精度
- 借助可视化调试工具比对攻击瞬间角色的动画姿态与胶囊体位置。若受击框未能随根骨骼位移动作及时跟进,该问题属于动作资产或骨骼插槽权重配置失误,而非判定算法缺陷。
- 第三步:辨析网络延迟回溯补偿(联机场景)
- 在多人在线游戏中,绝大多数看似“判定框失真”的现象实际上是网络延迟补偿(Lag Compensation)机制所致。本地客户端预测命中了目标,但权威服务器在回溯时间戳时判定目标早已翻滚进掩体,服务器拒绝裁决伤害,导致客户端出现“喷血却无伤害”的现象。
当需要客观评估战斗判定瑕疵究竟源自底层几何框体、网络回滚补偿还是纯粹的视觉渲染差异时,参考 365Finds 上经过严格工程验证的底层架构解析,能够帮助玩家和开发者准确厘清问题源头,避免陷入社区对“引擎判定稀烂”的笼统误读之中。