骑砍战团引擎浅层剖析(三)碰撞机制
在骑砍战团的1.161的modsystem(mod制作系统简称ms)中开放了一个新的操作cast ray,可用于检测碰撞,这个碰撞检测机理在unity中也有,所以这算是一个阉割版的UnityEngine.Physics.Raycast功能。基础原理都是从一个给定点发射一个无限长的射线或者给定长度的线段,当target层发生碰撞(相交),碰撞后得到碰撞体的信息,并返回值用于获取碰撞的物体id和碰撞位置等信息。但是骑砍的这个Raycast功能不能指定碰撞层数(只能返回第一个碰撞层),能获取的信息也只有前面所说的碰撞的物体id和碰撞位置(标准的UnityEngine.Physics.Raycast功能可以获取的返回值及相关参数如下图),所以我才叫它是阉割版Raycast。

虽然castray功能出现在战团的1.161ms中,但并不能说明这是战团的一个新技术,其实经过一些测试发现,部分骑砍的碰撞是基于这个技术的,只不过直到1.161才将这个碰撞技术部分开发给mod制作者使用。那骑砍的碰撞究竟是怎样实现的呢?
首先人的碰撞大部分不靠castray,如果你有半条命或CS的基础,就会发现骑砍的人单位和半条命模型动作处理上某些地方有相似,就是采用了hitbox(然而骑砍采用了模型动作贴图分开管理,所以限制了单位多样性,但有利于大战场优化,半条命采用模型动作贴图封装于一个mdl,对单体优化有提高并且可以让单位多样化比如树木桌椅也能使用骨骼动画,当会面临顶点上限等限制,所以半条命2就模仿md5mesh的模型技术将动作贴图分离出mdl进行改进了),就是从人体身上取几个关键点(手脚头武器点等等)的坐标,因为骨骼动画就是根据这些点进行对时间的矩阵变换形成一系列动作帧,所以理论上引擎可以实时获取这些动态改变的hitbox坐标点,有了脚的坐标点,就可以控制这个点与地面坐标的关系做到地面碰撞检测防止人物走着走着就沉下去或浮空;有了武器的坐标点,就可以将武器绑定在人体的合适武器,并且可以由此判断攻击范围(武器坐标Y坐标前移一个武器长度,1.161后可获取武器的长度重量等相关数据)进而实现攻击判定。
场景物体在开启Physics dynamic即动态物理效果后,就会具有实时碰撞检测特性,这个我猜测是基于castray的,并且动态物理效果战团历来就有,早于1.161,所以我说,castray其实本身就是战团引擎的碰撞检测功能,并非1.161开发仅为并非开放而已。至于为什么我推断dynamic状态的场景物碰撞判定使用了castray,因为我之前用过castray进行过碰撞试验,发现射线的密度和碰撞面的棱角程度对碰撞检测的灵敏性有影响,比如射线较少的时候,如果碰撞层是一个锥子而不是一个模型面较小而密的多面层或者整个碰撞接触面一两个模型面射线密度很小或涵盖几乎全面射线区域(即单个模型面很大,模型表面很平坦),你反复在这个碰撞阻隔的面上前移并且左右摆动,就会有几率碰撞检测失效而穿过碰撞面。而这一点在开启Physics dynamic后的场景物上也具有这样的碰撞检测局限(即碰撞面的平坦程度和模型单面与碰撞层的大小比例会造成碰撞判定不灵敏),所以推测开启Physics dynamic后的场景物碰撞是基于castray的,并且不开启Physics dynamic后的static状态的场景物与人相对移动产生的碰撞效应也是基于castray。也就是因为它采用castray群发射线,所以这样的场景物和大量的人群冲撞,会直接卡顿一两秒。
顺便说一下,骑砍的castray和UnityEngine的castray还有一点特性也是满足的,就是从有碰撞体的模型内部往外射线是不能检测到碰撞的。所以要把一个物体限制在另一个物体内部运动是不采用castray碰撞检测原理的。