☰
层次结构(Hierarchy):一层层装盒子
2026/10/17 1:42:55 网站建设 项目流程

一句话:把物体一层一层装进大盒子里。检测时先看大盒子,大盒子没碰到,里面的东西就全部跳过。

它属于上次说的粗检测,作用是:物体很多时,少检测一大半。


一、生活里的例子:找快递

快递员送一个包裹,不会挨家挨户敲门问"是不是你的",而是:

省 → 市 → 区 → 小区 → 楼 → 门牌号

每走一层,就排除掉一大片。“不在这个省”,这个省里几千万户就都不用看了。

碰撞检测的层次结构就是这个思路。


二、游戏例子:一颗子弹,8 个敌人

没有层次结构

子弹要和 8 个敌人挨个检测,一共8 次。

有层次结构

先把敌人分组,每组套一个大框,大框再套更大的框:

[整个场景] / \ [左半边] [右半边] / \ / \ [左上] [左下] [右上] [右下] ● ● ● ● ● ● ● ●

子弹飞在右下角,检测过程:

步骤检测结果
1左半边的框❌ 没碰到 →里面 4 个敌人全部跳过
2右半边的框✅ 碰到了 → 往里看
3右上的框❌ 没碰到 → 里面 2 个跳过
4右下的框✅ 碰到了 → 往里看
5、6右下的 2 个敌人精确检测

一共6 次,比 8 次少一点,看起来没省多少。

但物体一多,差别就很大

敌人数量挨个检测层次结构(大约)
88 次6 次
10001000 次20 次左右
100 万100 万次40 次左右

因为每往下走一层,就排除掉一半。


三、两种常见的分法

1. 按"物体"分组:包围盒层次(BVH)

就是上面的例子:把靠得近的物体装进同一个框,框再装进更大的框。

┌───────────────────────────┐ │ ┌─────────┐ ┌────────┐ │ │ │ ● ● │ │ ● ● │ │ │ └─────────┘ └────────┘ │ └───────────────────────────┘ 框住物体,框的大小跟着物体走

Unity 的 2D 物理(Box2D)、3D 物理(PhysX)内部用的都是这种。

2. 按"空间"切:四叉树

把地图切成 4 块,哪块东西多,就把那块再切成 4 块:

┌───────┬───────┐ │ │ ● │ ● │ │ ● ├───┼───┤ ← 右上角东西多,再切一次 │ │ ● │ │ ├───────┼───────┤ │ │ │ │ │ ● │ └───────┴───────┘

3D 里每次切成 8 块,叫八叉树。

BVH四叉树
怎么分按物体分组按地图切块
适合物体会移动地图固定、物体分布不均

四、另一种层次:一个角色身上也分层

这个在游戏里非常常见——爆头判定。

┌───────────┐ ← 第 1 层:整个人的大框 │ ┌───┐ │ │ │ 头 │ │ ← 第 2 层:身体各部位 │ ├───┤ │ │ │ 身 │ │ │ ├───┤ │ │ │ 腿 │ │ │ └───┘ │ └───────────┘

子弹先检测整个人的大框:

  • 没碰到 → 头、身、腿都不用查
  • 碰到了 → 再查打中哪个部位
打中部位伤害倍率
头× 2
身体× 1
腿× 0.7

《CS》《使命召唤》这类射击游戏都是这么做的。


五、代码长什么样

核心只有一个规则:大框没碰到就 return,碰到了才往里看。

classNode{publicRectbox;// 这一层的大框publicNodeleft,right;// 下一层publicList<GameObject>objects;// 最底层才有:真正的物体}voidQuery(Nodenode,Rectbullet,List<GameObject>result){// 大框都没碰到,里面的全部跳过if(!node.box.Overlaps(bullet))return;if(node.objects!=null){// 到了最底层:把这里的物体交给"细检测"result.AddRange(node.objects);}else{// 还没到底:继续往下一层看Query(node.left,bullet,result);Query(node.right,bullet,result);}}

六、要注意的坑

问题说明
物体移动了框要跟着更新,否则会漏检
框画得太大很多框都"碰到",就排除不掉东西,变慢
物体很少十几个物体直接挨个检测更简单,没必要建树

七、和你有什么关系?

  • 用 Unity:引擎已经内置了,不需要自己写。场景里放几千个 Collider 也不卡,就是因为它。
  • 自己写引擎 / 物体特别多(弹幕游戏、大量单位的 RTS):才需要自己实现。

顺便区分一下:Unity 编辑器里也有一个Hierarchy 窗口,那是管理物体"父子关系"的列表,和这里说的碰撞层次结构不是一回事。


一句话总结

层次结构 = 一层层装盒子。先查大盒子,没碰到就整组跳过,碰到了才往里看。物体越多,省下的检测越多。


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询