Unity3D 游戏同步浅析(五):帧同步


帧同步是指客户端之间只同步用户的输入指令,例如,向前走、按下哪些技能等等,不同的客户端各自计算自己的结果。由于消耗的流量只取决于指令数,因此会大大减少消息。另外由于消息结构原因,帧同步的速度要比状态同步更快,因此适用于一些高频交互的游戏。

不过由于每个客户端需要独立计算,因此需要保证计算结果的一致性。理论上讲,相同的时机,输入相同的内容,会得到相同的结果。不过从实际情况看,做到完全相同还是有些难度。以Unity引擎为例,一方面各个脚本之间Start、Update等生命周期函数的调用顺序不确定,另一方面,使用Physic物理系统也不保证是确定性模拟。比如一个单位的坐标偏差了0.01导致技能未能击中目标,那么这个目标的血量判断就会受到影响。如果这个目标的行为受到血量的影响,最终结果会完全不同。因此让每个客户端计算结果完全相同不是一件容易的事。有些常见的注意事项:

  • 不使用浮点数,用整数代替。
  • 不同客户的同步频率要保证一致。
  • 随机种子相同,并自定义接口防止其他公用系统干扰。
  • 使用排序容器,保证遍历顺序。
  • 逻辑显示分离。
  • 使用补间过渡,调整速率,掩盖卡顿。

除了一致性的难点,帧同步还需要解决流畅度的问题。因为通过网络传输过来的数据一定会慢于本地,而我们又希望在相同的时刻输入信息,那么就会引发等待,反映到用户体验就是不流畅。

优化方法有很多,例如,在帧同步游戏中,由于广播的频率非常高,因此每次广播的数据就要足够小,这样可以节省很多消息处理的时间。对于消息,可以将需要所有客户端同时发生的内容提前广播给其他用户,采用时钟同步。客户端逻辑先行,显示通过平滑追赶的方式处理。很多改进是体验优化的范畴,需要结合具体游戏进行。

在传输层,移动端的同步建议使用UDP作为传输协议。TCP为了保证传输的可信性,很多机制不太适合波动较大的移动网络。在弱网络环境下,UDP的RTT几乎不受影响,而TCP的RTT波动比较大,特别是在丢包重发时影响比较明显。虽然使用UDP会引入丢包、乱序的问题,但可以通过冗余的方式来解决整个问题。比如每个帧数据包,实际上是包含了过去2帧的数据,也就是每次发3帧的数据,来对抗丢包。

本文出自 松阳论道 转载必须注明出处

http://blog.songyang.net/5761.html

说点什么吧...

电子邮件地址不会被公开。 必填项已用*标注