关于魔兽争霸中的碰撞与寻路

前言

稍微讲讲《魔兽争霸 3》中的碰撞体积、碰撞类型、移动类型等等。

碰撞

单位的碰撞分为两种,姑且名为「攻击碰撞」与「寻路碰撞」,这两者都由单位的「碰撞体积」这一参数决定,但两者区别很大。

攻击碰撞

所有单位的攻击碰撞是个圆形(半径为碰撞体积的值),计算攻击距离、范围技能效果时,都使用这个碰撞。
碰撞体积是多少攻击碰撞就是多少,超过 1024 都可以。
攻击碰撞中心也是单位的实际坐标位置。

在 FPS 与 FTG 中,这个概念也叫做命中框(hitbox/hurtbox),是其玩法的一个核心概念。

寻路碰撞

正方形碰撞来源

地面单位的寻路碰撞是个正方形,也因此魔兽只有十字围杀而没有 X 字围杀,该碰撞只在寻路时使用。
寻路碰撞中心也是单位显示模型的位置。
地面单位的寻路碰撞一共只有 4 种,相当于 16 / 32 / 48 / 64,对应边长为 32 / 64 / 96 / 128 的正方形。
碰撞体积为 0 ~ 15.99 时,寻路碰撞为 16。比如所有被网下来的空军。
碰撞体积为 16 ~ 31.99 时,寻路碰撞为 32。比如农民的碰撞体积是 16,步兵是 31,他们的寻路碰撞都是 32。
碰撞体积为 32 ~ 47.99 时,寻路碰撞为 48。比如火枪手、蜘蛛和大多数英雄。
碰撞体积为 48 以上时,寻路碰撞为 64。比如坦克、山岭和少部分英雄(牛头人酋长、深渊魔王和驯兽师)。

在以前一些介绍碰撞体积的文章中,32 / 48 / 64 这三种寻路碰撞的单位也被称为小/中/大型单位。

另外很坑的一点是,寻路碰撞为 32 和 64 的单位的攻击碰撞中心与寻路碰撞中心不一致,寻路碰撞中心向左下偏移了(16, 16)的距离,也是 18 年我做移动幻影时才发现的事。(飞行单位等也会有偏移,但建筑不会)

坐标偏移

慕斯:那为什么不能是 16 和 48 的向右上偏移了呢⊙▽⊙?
云狐:跟地形格子对比一下就知道了,除非你说整个地图的地形也偏移了。
慕斯:那你怎么知道偏移了(16, 16)呢 ̄△ ̄?
云狐:目测也看出来了,总不可能不是个整数吧,而且把红色步兵坐标设成(16, 16)之后两个步兵就重合了。

建筑物

建筑物没有「寻路碰撞」,它们可以阻挡其他单位是因为其「路径纹理」。
其「攻击碰撞」则由「碰撞体积」和「路径纹理」共同决定,取其叠加区域(并集),但计算范围技能效果时,又只计算建筑的「碰撞体积」了。

杂谈

其实在编辑器界面中摆放单位的时候寻路碰撞是与攻击碰撞完全一致的,也是圆形,且和碰撞体积的值完全相同,也没有坑爹的偏移问题。因此可以推断在暴雪的设计中攻击碰撞与寻路碰撞应该是一致的,但由于技术问题,寻路碰撞简化成了四种正方形。

具体来说,主要是寻路算法的问题,寻路算法本身就比较复杂,并且 RTS 中单位数量多、地形复杂,不进行优化 CPU 负担不起,魔兽中为了不让寻路占用过多资源,还对寻路上限进行了限制,实测中每个玩家 50 个单位同时移动基本流畅,到 64 个单位开始卡顿,80 个开始卡顿较为严重。主要是魔兽发售于 02 年,以现在的计算机性能,承担每个玩家 100 个单位的寻路不成问题。
总之,所有移动物体和障碍都由 16×16 的正方形组成,更有利寻路算法的优化,也阴差阳错地催生了经典的十字围杀。

随着电脑性能和暴雪程序员技术的提升,到了星际 2,寻路碰撞就变为顺滑的圆形了。

移动类型与寻路类型

移动类型一共分为 11 种,对应 4 种寻路类型,默认为地面寻路,分别为:

  • 步行(步兵)
  • 骑马(骑士)
  • 浮空(女巫)
  • 飞行(狮鹫):飞行寻路
  • 漂浮(船):海面寻路
  • 两栖(娜迦):两栖寻路
  • 没有(关闭碰撞)
  • 疾风步(使用「疾步风(AOwk)」后获得)
  • 地雷(添加「地雷引爆(Amin)」技能后获得)
  • 无法移动(约等于定身)
  • 未知(没什么用,目测等价于「没有」)

步行、骑马、浮空没有什么区别,唯一不同就是浮空单位不会触发「地雷引爆」技能(还能设置高度什么的)。

碰撞类型

碰撞类型分别为:

  • 任意
  • 地面
  • 海面
  • 两栖
  • 飞行
  • 可建造
  • 荒芜之地
  • 矿工采集

移动类型和碰撞类型得一起讲。
一个单位只会有一种移动类型(其实可以有多种,但基本不用管)。

碰撞类型通常由移动类型决定,步行就是地面碰撞,飞行就是飞行碰撞,没有就是任意碰撞(存疑)。

也有一些特殊情况能改变移动类型和碰撞类型,比如使用「疾步风」能变为「疾风步」的移动和「矿工采集」的碰撞、添加「地雷引爆」能变为「地雷」的移动和「可建造」的碰撞、添加「龙卷风漫步者」能变为飞行移动和飞行碰撞。
这些情况下单位的寻路类型并不会改变,比如地面单位添加「龙卷风漫步者」后寻路时仍然会试图绕过地面障碍,飞行单位使用「疾步风」后寻路仍会无视墙壁一头撞上去,撞墙后才会重新寻路。

一个单位的寻路类型基本无法改变,除非用变身之类的,因为变身已经算是另一种单位了。

移动类型决定了单位自己的寻路类型,碰撞类型决定什么东西会阻挡单位以及单位会如何阻挡别人。
碰撞类型为飞行 / 矿工采集 / 可建造的单位不会阻挡其他单位。

每一块地面都包含以上这些通行性的属性:地面通行、飞行通行、可以建造等等。单位的「寻路碰撞」和建筑、可破坏物、地形装饰物的「路径纹理」也会改变其所在地面的这些属性(路径纹理的颜色就不细讲了)。

每个单位根据自己的寻路类型,以及全地图的地形和其他所有单位的碰撞,决定了每个单位最终的移动路径。所有这些属性构成了魔兽 3 中的寻路系统。

注:

  1. 触发中的几条开关可通行性互相独立,举例就是:关闭目标地点的两栖后,两栖单位不再能通过该处,但海面单位和地面单位仍能正常通过
  2. 每次关闭的大小是 32×32 的方块,坐标一定是 32 的整数倍,位置是方块的左下角
  3. 可以改变的仅限地形,比如悬崖、海面、不可建造地面,这条触发并不能覆盖单位、建筑、物品、可破坏物带来的碰撞
  4. 「任意」指的是其它全部的类型
  5. 「海面」会影响两栖单位的动画和潜水技能的施放
  6. 「荒芜之地」会影响对应单位的回血以及对应建筑的可否建造

路径纹理

路径纹理一般是给建筑设置的,它有两个作用:一是建造时判断能否建造的一个模子,二是作为建筑建造后的实际的寻路碰撞。
但如果给一个非建筑单位设置路径纹理,那么它的第一个作用仍然有效,但第二个作用就无效了,它的寻路碰撞仍采用那四种寻路碰撞。

关闭碰撞

关闭碰撞只改变移动类型为「没有」,使单位无视地形(包括地图边界)、无视其它单位碰撞,但不改变碰撞类型,所以仍对其他单位有碰撞。
关闭碰撞后虽然可以穿越任意地形,但仍然使用地面寻路,所以实际体验非常差,像 DotA 中幽鬼开 D 想要穿过悬崖只能一点点挪着前进。

矿工采集

农民采集金矿或木材返回后会变为「矿工采集」的碰撞类型,之后的采矿都会保持这个状态,发布任何命令都会取消这个状态,比如使用「送回资源」或右键点击老家,第一次采矿前也不会进入这种状态,对战中此状态下的移动速度还会有些许调整以保持稳定的采矿效率。
矿工采集碰撞类似于地面碰撞,所以跨海采矿是不存在的,即使是两栖农民。空军使用「疾风步」也会变成陆军似的不能穿越地面障碍。
物品和「疾风步」状态也对应「矿工采集」类型,物品还会阻挡其他「矿工采集」的碰撞。
如果用物品彻底堵住金矿和基地之间的路,农民会被卡住一会,然后会自动变回普通的地面寻路和碰撞返回基地。
正在采木和等待采矿的农民既会阻挡地面碰撞也会阻挡「矿工采集」的碰撞。

地雷引爆(Amin)

获得该技能会使得单位永久隐身,移动类型变为地雷,碰撞类型变为可建造,不能通过不可建造地面。
删除技能后除了永久隐身失效外,其余效果都会保留。

组群分离

空军会自动散开是因为「组群分离」的设置,把「组群分离」关了空军就不会散开了,暴雪本身只在所有空军上设置了「组群分离」,其实将「组群分离」设置在地面单位上也可以看到同样的效果。组群分离的效果和单位的碰撞无关。

结语

很多资料都作古了,勉强算是写完了。算是一篇集合各方资料的综述吧。

参考