帧同步技术是早期RTS游戏常用的一种同步技术。与状态同步不同的是,帧同步只同步操作,其大部分游戏逻辑都在客户端上实现,服务器主要负责广播和验证操作,有着逻辑直观易实现、数据量少、可重播等优点。
帧同步与状态同步相比各有各的优点。
不管我们当前用不用的到某些技术,但说不定我们以后会用到,所以多一份技术傍身,一方面是为了壮大自身,能找到更好的工作。一方面是多一份技术,就多一份自信,多一份能力。
本篇文章是帧同步系列文章研究学习之路的一个记录之一。
环境
客户端环境:Unity2018
服务端环境:PhotonServer
使用到的技术
- 帧同步
- 锁帧
- UDP
- 定点数学库
- 强制同步帧
未使用技术
- 随机种子
- 帧同步物理系统
- 预测
- 回滚
- 回放
- 防作弊
- 断线重连处理
- 等等等等
帧同步核心
- 相同时机+相同输入
- 渲染与表现分离
- 避免精度损失
遇到的问题:
1.亲测Untiy的物理系统不靠谱,会产生不同步,尽量避免使用Unity的物理系统,摇杆移动角色最好自己使用定点数加以控制保证其位置绝对性。
2.客户端在必要时需要进行锁帧,保证所有客户端帧数的一致性,否则会造成延迟。
锁帧
为什么会有锁帧这个概念,主要原因是为了达到所以客户端的帧数一致性。
为什么会出现帧数不一致性?
主要还是因为网络问题导致所以客户端无法准确的在同一时间收到服务端下达的游戏开始或者逻辑帧开始的命令,不同的网络环境下每个客户端收到的消息的时间有很大的不确定性,如果不进行锁帧,比入在游戏刚开始的时候,服务端下发了一条逻辑帧开始的命令,有的客户端网络好收到的比较早,有的客户端比较慢,收到的比较迟,这就会导致,先收到命令的那个客户端的逻辑帧已经跑到了5帧左右,而后收到的客户端逻辑帧才开始跑。这种帧数不同步的情况就已经是一个错误。会造成逻辑优先的那个客户端有很大的延迟,因为每个客户端的同步帧是服务器一次性下发的,而帧优先的客户端,在第5帧做了一些事件,这个时候服务器不会立即回复第五帧的消息,因为服务器会等待所有的客户端的帧事件到达之后,才会进行同步帧的发送。而由于另一个客户端的逻辑帧比较慢,就导致服务器被迫跟着慢逻辑帧的客户端进行同步,而你走的快,发送的帧自然要等待另一个慢的客户端走到这一帧了才会收到自己的帧事件,所以就造成了延迟。(这里初步暂时使用的为等待式同步,并不是自动填充空帧式同步,目的式为了踏出第一步)
在刚进入游戏时,进行锁帧,等待与其他所有客户端的帧id同步时,在进行帧同步逻辑。
帧同步
相同的时机+相同的输入=相同的输出=帧同步的核心基础
UDP
因为帧同步的数据量比较频繁,且对延迟要求比较低,鉴于UDP传输速度比较快,所有可靠的UDP传输是非常好的选择,因为UDP相较于TCP能把延迟给我们降到最低。
同步方式
这里初步暂时使用的为等待式同步,并不是填充同步,目的是为了确定帧同步方案可行性。
等待式同步:
服务器每隔固定时间进行一次同步,但同步的时候会端等待所有的客户端当前帧的数据到达之后,进行同步。
填充式同步:
服务器每隔固定的时间进行一次同步,如果到达了同步点有某个客户端没有发来帧数据,直接填充空帧,不进行等待,然后进行同步。
定点数数学库
使用定点数学库的目的就是为了避免浮点型在不同平台带来的误差,由于不同平台的硬件等环境不一致,在相同的数据情况下,不可能保证得出的小数点结果完全一致。哪怕是有一点偏差,次数上来了,偏差也就大了。因此,必须使用定点数学库,来确定不同平台以及不同客户端的结果的一致性。
努力积才能,壹叶便成名。
喜欢我关注我,更多干货等着你!