现现在,网络同步的技术在各类游戏里被普遍应用和发展,那么,如何在Unity中搭建网络模块?如何使服务器和客户端之间通讯?如何作到网络同步?本文做者烂笔头-27将从自身经验出发,为你们一一解答这些疑问。
系列回顾:手把手教你实现Unity网络同步
8、物理碰撞的网络同步
写完上一篇文章以后,在Q群有一位朋友提了一个问题,在这个网络框架下,没法正常处理物体与物体之间的碰撞,通过测试之后,发现确实会出现这样的状况,如图:
html
能够看到,在客户端物体(蓝色立方体)移动,而后碰撞到服务器物体(红色立方体)时,因为服务器端的物体在客户端是滞后的,而客户端物体是本地预测的,当发生碰撞时,不能及时地产生碰撞反馈,因此致使碰撞的结果两端不一致,而后客户端就预测失败,产生很强烈的抖动和拉扯。这显然不是咱们想要的结果。
那么如何来解决这样的问题呢?
1.思路
缘由已经找到了,由于在客户端,客户端的物体是本地预测的,而服务器的物体是根据收到的状态包进行插值,二者在当前时刻,物理状态有差别,因此致使的碰撞异常,既然是由于服务端和客户端的物体,模拟的步调不一致致使的,那么可不能够在客户端去预测服务端的物体,使二者可以保持相同的模拟步调呢?
在GDC2018演讲 《火箭联盟》的物理与网络细节(须要***)这个视频中,从37分22秒开始,演讲者演示了在《火箭联盟》中是如何作到在客户端对服务器的球的物理状态进行预测。
所以,在“巨人的肩膀上”,在以前的网络同步架构之下,作一点拓展,使在客户端预测服务端物体的物理状态。
2.模仿《火箭联盟》制做汽车(Car)和球(Ball)
新建一个预设Car,样子大概这样:
服务器
新建一个预设Ball,样子是这样:
网络
为了让球(Ball)更像真实的球,给它添加带弹性的物理材质:
架构
3.为汽车(Car)和球(Ball)添加控制逻辑,以及须要同步的网络状态。
汽车的控制代码:
框架
球(Ball)不接收按键输入,只有须要同步的物理状态,物理状态跟汽车(Car)是相同的。
测试
就这样,汽车(Car)和球(Ball)都建立好了,能够进行基本的碰撞同步检测了,效果如图:
spa
能够看到,在汽车(Car)冲撞到球(Ball)以后,球发生了剧烈的抖动,接下来,就要解决这个问题了。
4.在客户端为服务器物体进行物理状态预测
在目前的同步框架下,服务器的物体在客户端是基于状态进行插值变化的。因此是滞后了,为了能在客户端预测它,咱们能够建立一个假的球(DummyBall),而后把真正的球(ServerBall)隐藏(PS:仅仅是隐藏,同步逻辑仍是同样的),这样,就能够作到
>汽车(ClientCar)不和ServerBall发生物理碰撞,只和DummyBall发生碰撞。
>能够在客户端对DummyBall进行物理预测,而不是影响ServerBall。
这可能有点绕,简而言之,就是为了在客户端预测服务器的物体,客户端建立了一个假的”欺骗”玩家,但不是真的欺骗,DummyBall在预测以前的物理状态必须是服务器下发的最新状态,DummyBall的代码以下:
3d
而后客户端为本身(ClientCar)作预测的同时,也为DummyBall作预测,代码:
视频
在汽车(Car)的执行操做指令的逻辑中,由于Physics.Simulate()是全局的,因此客户端预测执行一次,DummyBall也预测模拟了一次。
htm
看看效果吧(蓝色车是客户端控制,紫色球是假球DummyBall,都是客户端作预测的):
能够看到,在客户端的预测下,汽车(Car)碰撞到球(Ball)时,产生了很及时的碰撞反馈,此方案可行。
再把真实的球(ServerBall)给显示出来对比一下(蓝色车是客户端控制,紫色球是假球DummyBall,都是客户端作预测的,红色球是ServerBall,是由服务器下发的状态包来作插值):
5.小结
经过建立DummyBall在客户端实现对服务器物体的物理预测,虽然感受像是玩家在踢”假球”,可是能够换个说法,玩家是在踢”将来的球”,这样听起来就很Amazing了~
在不肯定性的物理模拟和较高的网络波动环境下,这样的作法总会发生偏差,为了减小偏差带来的游戏体验,在带宽容许的条件下,能够尽量的增长网络传输的频率,好比:20个包/秒,还有对数据流量进行压缩也颇有必要。
来源:腾讯游戏学院
原地址:https://mp.weixin.qq.com/s/y7oa6eGkclI1NkcOOwplXA