帧同步和状态同步

网络同步

网络同步主要目的在于保证各个端口的游戏表现一致,网络同步就在于实时的多段数据同步和实时的多端表现。

而对于大多数游戏,不仅客户端的表现要一致,而且需要客户端和服务端的数据是一致的。所以,同步是一个网络游戏概念,只有网络游戏才需要同步,而单机游戏是不需要同步的。

帧同步与状态同步的区别

概念

  • 帧同步(Lock Step):同步的是客户端的操作指令。客户端上传操作到服务器,并且服务器并不做过多的处理,然后将当前帧间隔内收集到的操作指令广播给每一个客户端,各个客户端在一致环境下,处理同样的操作输入,则会得到同样的结果。

帧同步和状态同步_第1张图片

  • 状态同步(State Synchronization):同步的是游戏中的各种状态。一般的流程是客户端上传操作到服务器,服务器收到后计算游戏行为的结果,然后以广播的方式下发游戏中各种状态,客户端收到状态后再根据状态显示内容。

帧同步和状态同步_第2张图片

逻辑计算

战斗逻辑在帧同步中是在客户端计算,在状态同步中是由服务端计算的。

帧同步下服务端只进行转发操作,不进行逻辑处理。但是计算逻辑必须知道涉及计算的实例情况,因此大型多人游戏(MMO)就必须交给服务端计算,因为远距离的单位以及场景都不显示,客户端没有足够信息计算全图的行为

状态同步下,客户端只是对服务器传来的数据进行显示而已,并不能改变它。具体场景中:空护短检测到玩家开枪发射子弹 —— 服务端通知子弹的发射方向和模型数据 —— 客户端根据信息创建游戏物体,本地计算子弹接下来的位置 —— 碰撞检测后服务端通知客户端 —— 客户端播放敌人受击效果等视觉效果

因此,状态同步流量消耗更大,因为他每次都要同步并通知所有的属性,帧同步只需要转发就够

实时性

帧同步中因为逻辑一般是客户端执行,这样能更快的转发消息。客户端需要将指令同步后在固定间隔内进行逻辑计算,而不能计算好之后再发送给其他客户端。因为在不知道其他玩家的操作下进行计算会造成结果不一致,比如AB同时攻击了对方,可能在自己客户端视角都认为是对方先死,但是同步计算之后会根据最先攻击时间来计算,确保结果唯一。但要实现结果唯一就要求所有客户端都有相同的随机种子,也就是客户端随机出同一结果,这也要求指令不能丢失,所以要用TCP等可靠传输协议。

状态同步其实不是严谨的同步,因为不同客户端的表现不一致在他看来是可以容忍的,只需要每次操作的结果相同即可。因此他对网络延迟的要求并不高,所以广泛用于回合制游戏当中。

由于不可能保证百分百的实时同步,开发过程中都会用一些技巧来掩饰:

  • 根据游戏的具体情况,加一些前摇动画来掩盖延迟

  • 客户端只负责一些模型、动画,它会根据绑定的逻辑对象状态来进行一个插值,这样可以做到逻辑帧率和渲染帧率不一样,但是做了插值平滑和逻辑表现分离,画面不抖了

  • 把远端数据缓存在一个buffer里面,然后按照固定频率从buffer里面取,可以解决客户端卡顿以及网络抖动问题。

断线重连以及回放系统

帧同步的回放比状态同步好做得多,因为只需要保存每局所有人的操作就好了。但是实时回放的话(比如死亡回放),客户端需要本地对全场状态进行序列化,才能回到目标时间。播完回放后还需要加速追上实时游戏状态

而状态同步的回访,需要有一个回放服务器,当一局战斗打响,战斗服务器在给客户端发送消息的同时,还需要把这些消息发给回放服务器,回放服务器做储存,如果有其他客户端请求回放或者观战,则回放服务器把储存起来的消息按时间发给客户端。守望先锋的死亡回放、全场最佳、赛后回放使用了另一个EntityAdmin(ECS的术语)

但是断线重连则相反,因为帧同步将数据大多放在客户端,重连时倍速播放服务端同步的帧数据来跟上正常进度。状态同步只需要根据服务端记录下的状态信息创建对象并同步就行了

客户端帧与逻辑帧

  • 逻辑帧:逻辑帧一般是处理一些跟服务器需要交互的数据,是各个客户端同步的关键数据,如玩家的移动指令,释放技能操作等。逻辑帧的帧率一般推荐1秒10帧,要考虑操作响应及时、数据吞吐能力、网络稳定性等因素。
  • 客户端帧:客户端帧是依赖于逻辑帧下,表示当前逻辑帧内,依据当前的数据环境中,客户端依据客户端帧去计算逻辑。很多逻辑判断都是在客户端帧中去进行,逻辑帧更多是同步一些操作指令等,是处理数据上传、分发。客户端帧跟逻辑帧是严格对应的,且同样是有序,客户端帧率一般是逻辑帧的整数倍,客户端帧是受逻辑帧驱动的,逻辑帧增加,才会触发客户端的触发,从而推动游戏的逻辑计算。

如果设定的逻辑帧能满足自己游戏的逻辑运算需求,可以不需要客户端帧

你可能感兴趣的:(unity,网络)