参考: http://fabiensanglard.net/quakeSource/quakeSourcePrediction.php
http://fabiensanglard.net/quakeSource/johnc-log.aug.htm
服务端物理的broadphase阶段处理基本有3种方案:
1:uniform grid, 统一尺寸网格
2:sweep and prune
3: dynamic aabb tree
其中sweep and prune 可以参考box2dx, 而dynamic aabb tree 参考现代版本的 box2d实现。
服务器上如果使用类似box2d的精确物理碰撞实现,例如支持多边形碰撞,消耗确实不小,略微看了box2d的多边形碰撞实现,计算量还是比较大的;
退而求其次,首先将物理世界以unity单位0.5*0.5尺寸,切割为网格,将障碍物的aabb所占用的网格标记起来,当 坦克移动的时候,和网格进行碰撞检测,只做简单的AABB碰撞检测,运算量较小,与传统的基于网格的网络游戏,相比,复杂度是高一些的,但比box2d物理引擎要简单很多。
服务器上实现了aabb 轴对齐 统一网格障碍物判定之后,客户端就可以只需要同步速度到服务器上即可,而服务器来进行位置计算,流程:
1.客户端发送当前控制速度到服务器;
2.服务器房间启动一个物理更新的Task协程处理,定期根据玩家的速度更新服务器上玩家位置,同时进行物理碰撞计算
3:服务器将玩家在服务器上的位置广播给客户端
这里我们的服务器采用固定帧率,例如100ms一次向客户端广播服务器上玩家位置;另外一方面,服务器上以固定50ms作为物理世界刷新的频率, 每50ms计算一次玩家的当前位置。
如果客户端没有移动预测,就会存在一个问题,客户端上的玩家需要等待100多ms才开始运动,因此需要引入客户端移动预测,当
1.玩家操控的时候,立即将操控的移动速度传给玩家状态机,由状态机开始运动;
2.同时将玩家操控信息发送给服务器;
3.当服务器上玩家位置广播回来时,将其转化为一个操控命令,传送给状态机,这样对于玩家客户端状态机来讲,其都是只接受一个移动速度命令,而不关心这个命令是客户端预测发送的,还是服务器广播的。