Warband engine analysis(战团引擎浅层剖析)(to be continued待续)

killyouready

Regular
Best answers
0
This post is later to be translated in English,mainly to explain the Warband engine's mechanism by my experience and to be irregularly updated:


骑砍战团引擎浅层剖析(一)武器物品和场景物的内在联系和同源性
我之前就提到过,骑砍凡是一切模型资源关联的模块都可以看作是对一个模型的场景基础功能在引擎里加以功能延伸或限定来分化出troop(人)、item(武器衣物生活用品)、horse(马)、sceneprop(场景物)、particle(特效粒子)、mesh(界面模型)这些模块。

第一期我讲讲item武器类型的物品和sceneprop场景物类型的物品的引擎层面的联系。通过试验可以发现,当一个人中箭的时候,对这个人或身上的箭进行任何移动类代码控制都不会使得箭离开插入人体的相对位置,而如果箭击中的是场景物类型的物品,对场景物进行移动类代码控制,就会发现箭停留在原来的位置哪怕悬空。

接下来不得不提到骑砍mod系统的一种命令,就是propattach命令,用于将场景物与人体某个相对位置永远绑定且过程不可逆,也就是不能解除绑定,而且被绑定后就会使这个场景物不再适用于移动类命令,这种现象就像人被箭和标枪射中时的状态一样,而mod系统允许我们获取攻击击打目标的坐标和身体hitbox点的坐标,所以其实这种中箭的过程完全可以用场景物模拟出来(但是肯定没有引擎对这方面的优化好)。至于引擎为什么要这么设定,很简单,你被射了箭乱动后箭离开身上悬空在原地不是很僵?

而场景物被射中箭移动场景物后箭会悬空在原处是因为,场景物的移动类代码控制和人的移动类代码控制不一样,首先人的移动一般只有xy轴(z坐标会自动变成距离地面最高碰撞点上,这也就是人物飞行在骑砍一直不太好做或做出来很僵的原因)并且还受到地面坡度改变ai的相关反应不按线性移动,而场景物是在三维空间你让他怎么移动就怎么移动,单纯命令它移到半空也不会落地。所以射中箭的场景物可以看作箭从武器点修正与发射者视点的相对角度按一定速度(考虑模拟重力阻力修正方向和速度)移动到与目标场景物检测碰撞反应的点处,然后停止移动且它们之间没有绑定关系。至于引擎为什么要这么设定,很简单,因为大多数mod不会想要做让场景物移动的功能,所以有些物理特性引擎不必要搞出来(虽然骑砍系统是有支持场景物的物理特性的)

但是这还不够说明武器类item和场景物品prop在引擎层面的深度联系甚至说同源改造,那就要提到循环命令场景物的命令,它可以使已经主动或因死亡丢弃的或者插入其他场景物或地面的武器受到命令影响,这说明引擎把我前一句所说的那种状态下的武器item看作了一个没有碰撞体的场景物去处理;

而插入人身体的武器不受影响因为原理类似于attachprop命令的影响导致这一类对移动类命令失效(PS:手上拿的武器也是同理attach,因为武器的绑定位置是一个可以被获取的人体hitbox坐标)。

所以综上,在引擎内部,item武器类型的物品和sceneprop场景物类型在一定程度是属于同源改造,拥有大量通用适用的基础功能,然后根据各自在游戏中的用途做出适当限定和针对性延伸,使得某些情况下对模型资源的功能赋予更加的通用化和调用快捷化。

(可以再通俗解释一下,比如骑砍对于兵种类模型资源的功能赋予,会把士兵分队或分成骑兵步兵弓兵,就是一种类的细分,为了在一些具体的细节情形上方便操作,对同类事物继续分化分类,武器类也不用说,分为单手远程等等,场景物在1.161版本后也是有特性分类也可以自己设定条件分组,所以很多东西不用分立的去看,它们可以是相同的大类,也可以是根据具体情形特性条件分化的小类。然而只是有些东西常常被世人习惯分开看待,或者使用上有侧重或者歧视或者有优先级之分,所以一些联系和本源就会被人忽略。简单点说,这就像人和动物的关系一样,还有他们的各种级别的物种分类)

骑砍战团引擎浅层剖析(二)摔伤机制
骑砍的摔伤完全不是根据下落高度及落地速度,单纯以落地(准确来说是agent正下方场景物或地面的最高碰撞面)速度结算。而士兵的自由落体运动于引擎中控制,故运行先于mod系统中对人和物体的位移控制,加上本身的效率问题,所以命令向下移动在空中agent(人)脚下的场景物速度过高时就必然会使agent(人)与场景物原先的接触产生微小分离,再加上本身骑砍native也不需要考虑太复杂的摔伤情况所以伤害计算也就相当粗暴,导致agent(人)双脚重新接触场景物表面的瞬时相对速度过大,进而产生致死摔伤触发。

然后再说说骑砍的自由落体运动学特性,本身骑砍从特高空(比城墙高许多)自由落体时agent(人)先是加速最后会匀速,也就是官方基于native预想了一个最大摔伤,然而并没有想过由于moder想要动摔伤机制另一个关键因素落地点(特别是预期坠落的场景物体)或者利用运动的场景物改变agent(人)运动状态(例如速度和方向),导致这些条件的出现使得agent(人)突破了那个特高空自由落体最后保持的匀速速度,进而产生了超越官方预期最大摔伤计算的巨大摔伤伤害。(做过试验,如果用前面的方式强甩人,600力量也不经摔)

典型的例子:

1.有的人做飞机功能时刚开始会头疼飞行员摔伤或者空中急转弯极易触发摔死的问题。

2.如果用一根有碰撞的棍子半空中以正常单手武器手速砸下一个不足人高开始自由落体的人,甚至会造成基于挥甩速度的速度加成迅速落地触发致死摔伤。

骑砍战团引擎浅层剖析(三)碰撞机制
在骑砍战团的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碰撞检测原理的。

骑砍战团引擎浅层剖析(四)人与场景物机制的异同

第一期讲了武器和场景物有一定同源的引擎功能和机制,本期讲讲人和场景物功能机制上的同源性。

从总体层面上,其实人可以看成是一个被条件写死一些运动和碰撞特性的Physics(动态)场景物,而战团几乎全部现有场景物可以看作是默认关闭动态物理效果的static(静态)场景物。

为什么这么说呢?首先人(agent即troop中的一个个体实例)与场景物(sceneprop)都有可以关闭开启的动态物理效果,开启关闭后一些运动碰撞特性有很多相似的地方。区别是:

1.在旋转运动方面,人在引擎内部有一个校准地面坡度的设定,使得无论是Physics还是static状态的人不处于撞倒杀伤的情况下会保持身体与地面垂直的空间相对位置关系,使得无法使用旋转的基础操作对人体进行对x或y轴的空间位置旋转运动而场景物可以(所以这时候人的对x或y轴的旋转要靠动画了,不过对z轴的可以靠位置坐标变换)。

2.在平移运动方面,static状态的人没有开放在两个坐标间匀速动画式平移的功能(场景物在mod系统中有这一功能开放),不过可以用极限变换坐标实现static人移动(而Physics状态的人就是靠引擎的地面坡度检测和碰撞检测加上mod系统可修改层面的ai系统驱动移动)。

3.在箭矢攻击方面:Physics状态的场景物在箭矢击中的情况下也会呈现与Physics状态的人一样的中箭状态(即保持箭在射中相对位置随人或场景物的移动一起移动,而static状态的场景物中箭移动箭矢还是会处于原坐标位置),还有的不同之处是人在某些情况下会被动受引擎设定清除身上中的箭矢,而Physics状态的场景物在如今的mod系统中可以支持mod作者控制所中箭矢的清除(这并不是说明人和场景物在中箭效果上引擎层面有什么差别,应该是利用同一原理,只是对于mod作者来说只开放了场景物的箭矢清除操作,要搞清楚有没有和给不给的区别)。

4.在碰撞方面:在前面我讲了好多碰撞的东西,所以我再通俗讲一下碰撞检测机制到底是什么意思,就是当物体A移动的时候,保证A在开发者所设想的位移允许条件下,环境中不允许越过的其他物体就是障碍物,A在预期的移动方向上将与障碍物有表面或内部的坐标交叉,通过碰撞检测反应达到一定条件就会利用障碍物和A最先达到模型碰撞交叉的区域的坐标距离判定来阻止A在这个方向的移动(比如向前移动检测到快撞上障碍物就会触发某条件停止运行前进的移动代码)。所以不难看出碰撞检测的关键在于物体模型在游戏环境中的坐标的获取。而出于优化考虑,一般游戏获取坐标的方式有两个,一个是只需时刻知道物体身上的特征点(比如人,采用hitbox,只需要知道手脚头肩膀等等人体关键部位的一个或几个坐标就可以满足碰撞控制的需求),另外一个就是raycast,利用类似红外制导的射线对物体表面的坐标进行获取(比如Physics状态的场景物,不过骑砍mod系统也可以直接判断Physics状态的场景物是否交叉,但原理上还是对raycast的应用封装的功能)。

所以人和场景物在碰撞检测层面所用的坐标获取方面是不一样的,但是坐标获取后的判定碰撞原理是大同小异的,比如想在地面上走不沉下去只要能获取模型底面区域的坐标和地表接触区域的坐标就可以根据坐标距离来限制向z坐标反方向的移动代码即可,其他障碍物也是同理(把整个大地也可以看成一个障碍物或场景物,其实说法也没错,因为大地天空与部分石头树木在引擎里给过命名叫他们“环境场景物”,比那些正常的“装饰场景物”在mod系统上缺少大部分控制权限),顺便提一下,一般向前碰到障碍物对向前移动的代码进行限制的时候有的游戏里就算你只按W还会加一点对z轴旋转运动来致使单位可以被动绕开障碍物,不过骑砍不是,骑砍是只按W向前遇到障碍物就不能触发前移移动的代码了,这时候你就需要鼠标+W或ASD来绕开了(使控制体和障碍物体拉开碰撞判定的条件距离)。

5.动画方面:人和场景物都有动画,虽然所用动画形式不一样,前者采用骨骼动画,后者采用顶点动画,其实骑砍还有一种动画叫做UV动画,但应用上我们更习惯于把UV动画的应用归于Shader系统。还有,电脑上最早的3D模型动画是骨骼动画quake-MDL,而最早的顶点动画md2和md3技术是基于MDL的,而半条命的mdl技术和quake的是一样的,半条命二代的mdl是根据doom3开发过程的中间产物MD4改造的,所以事实上骨骼动画和顶点动画很多原理是差不多的,区别是优化和可维护程度,并且一定条件下可以互相转化。而骑砍的Physics状态的人动画和运动攻击互动等行为互为触发条件的,如果有耐心和基础,场景物也是可以根据此变成活物。所以这在人和场景物两者间从引擎层面上开发潜力没有多大差距。

6.通俗解释动态物理效果决定了什么:动态物理效果决定的就是物体的运动,前面所说的平移旋转自然是物体的运动,而前面所说的碰撞和动画也只是对物体运动的环境条件的限制调整以及触发条件或运动产生的后果。

所以综上所述:人和场景物功能机制在引擎内部具有同源性,对于他们的模型资源的功能设定上很多是相同的,不过根据游戏中的具体分工对一些基础功能进行了条件限定或者只是没有对mod制作者开放一些功能的控制权限。

题外话:骑砍的人和场景物在引擎里的关系这就像自然界人和动物的关系,有同一个祖宗,在自然界担任不同的分工,具体功能上出现分化,但还是有大量相似特征。不过人总以自己的标准评判是非愚智,不会画画算人类算术的动物就一定比会这些的大猩猩聪明?聪明的标准要看环境和场合,动物也有许多本事和智慧行为是人类无法做到的(比如声呐猫头鹰的夜视能力鸟类对猎物锁定的精准运算),但是一般不会纠结这个,因为分工不同,评价需要中肯客观。但是也可以互相学习,可以得到一些不可思议的提升,而且你也不能否定大自然这个造物者以后会让某个动物也进化出类似人的生物。

to be continued待续。。。。。。


Extra content:

some function of trial  in screenshoot: