游戏里的帧同步机制

游戏同步机制

在多人对战的游戏中,游戏的每一方客户端需要保持每一个时刻大家的数据是一致的,常见的同步方式分为帧同步和状态同步,帧同步服务器不需要知道游戏逻辑,只是将客户端的操作进行转发,然后客户端自己计算逻辑,状态同步是服务器计算游戏逻辑,并将角色状态返回给客户端,客户端直接使用服务器返回的状态即可。常见的RTS,Moba一般是帧同步,mmorpg一般是状态同步。

帧同步的概念

总所周知,游戏是一帧一帧渲染在屏幕上的,我们一般称之为渲染帧,渲染帧是不稳定的,如果一帧计算的东西太多或者画面太复杂,这一帧的时间可能会比较长,同一款游戏在不同的CPU,显卡上,渲染帧也是不尽相同的。而帧同步的帧是指逻辑帧,非渲染帧。我们以2台手机为例,他们需要同步,意味着他们的数据是一致的,如何保证他们数据一致呢,保证它们的起始状态是一致的,执行操作的时间是一致的,执行的操作是一致的,那么2台机器的结果一定是一致的。假如我们将游戏固定为1秒20个逻辑帧,即每50ms执行一次逻辑帧,2台手机都将在第5帧的时候执行A的移动操作,都将在第12帧的时候执行B的攻击操作,这样2台手机无时无刻不保持着一致,这就是帧同步的概念。

帧同步的准备工作

在做帧同步之前,需要头脑清晰的知道所有的游戏逻辑都需要拆成每个逻辑帧去执行,例如计算伤害,生命恢复等,这些都是在每一个逻辑帧去做的事情。游戏按照你的逻辑帧,不停的计算着数据,这样游戏就按逻辑帧走起来了,至于渲染到屏幕上,渲染30帧还是60帧,跟你的数据运算没有关系。

带关键帧的帧同步实现流程

  1. 设定游戏的逻辑帧率和关键帧率,在这我们假定游戏1s执行20个逻辑帧,每5帧是一个关键帧。
  2. 服务器1s向客户端广播所有的关键帧,在这,服务器每1s向客户端广播4次关键帧,每次广播内容为上一个关键帧到这一个关键帧之间玩家的所有操作,例如A在第7帧要执行移动命令。
  3. 客户端收到服务器广播的关键帧后,开始执行所有的帧操作,例如A在第7帧要执行移动命令。如果这段时间没有任何操作,意味着这段时间玩家没有操作。游戏每一帧都要执行正常的游戏逻辑,该回血的回血,该攻击的攻击,跟关键帧是否携带操作信息没有关系,只要收到关键帧,则一直执行到当前收到的最大关键帧为止。
  4. 客户端的每次操作不会立即生效,而是上传给服务器,客户端执行操作的时间都收到服务器发送的为准,服务器保证的是所有客户端都以同一帧执行该操作。

流程图如下: 帧同步流程图

细节相关

  1. unity的Update是渲染帧的每一帧,请勿将逻辑直接写在Update里,一次Upadte可能会跑好几次逻辑帧,也可能一次都不跑,但是可以用Update去调用逻辑帧的Update,需要自行判断当前时候可执行逻辑帧,以及应该执行几次。
  2. 客户端上传操作的时候,加上预计该操作执行的帧,因为客户端的帧比服务器的慢,加上网络延迟的原因,客户端实际执行该操作以服务器校验后的为准,比如A在第5帧做了移动操作,我们传给服务器的是预计第10帧进行移动操作,如果服务器收到该条命令的时候,还没有向客户端广播过第10帧的内容,无需额外设置,如果服务器收到该条命令的时候已经广播过第10帧的内容,则需要将操作的帧自动往后顺延到下一次的关键帧内。
  3. 抛弃掉浮点数,因为浮点数的运算跟CPU相关,不同设备计算出的浮点数会有误差,任何误差对帧同步都是大忌,可以自己实现一套浮点数,最简单的就是存成long类型,通过倍数转换实现,1000代表浮点数的1,0.001用1表示,自己按这套规则去运算就可以了。
  4. 随机数也可以自己实现一套,利用相同的种子,随机数就是一样的,这个也是在帧同步中必须保证的。

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦