比方说我和服务器约定每秒20帧,服务器以每0.05S是的时间广播消息, 客户端以同样的帧进行同步处理,, 理论上如果没有延时,整个位移是非常平滑的,,但是,如果网络不好, 客户端接收服务器的帧数据,都是大于0.05秒的,,比方说,网络不好,客户端收到服务器的每帧消息都是0.09S, 这个时候,客户端以每0.05秒的时间从帧缓存容器中去拿数据,就会出现拿不到的情况,就算是在刚开始移动的时候,先压几帧,但是因为网络不好,这几帧很快就会消耗完,这时候,在视图层就会发现,人物走动是一卡一卡的,,这种情况该如何处理呢,,
我做了一个办法,就是当从帧缓存容器中拿不到数据的时候,判断最后一帧是不是走动数据,如果是走动数据,就以这个数据的方向走几帧,等拿到数据的时候,再进行校准位置,,但是这种效果非常差,因为每一帧移动到哪个位置都是可以算出来的,,当预先走几帧,等收到服务器的消息进行校准的时候,角色会先移动到正确的位置,然后在根据后面的服务器广播的指令进行移动,,,做出来和卡顿的效果差不多,角色总是突然回头走然后再根据正确的方向走,,,,
邓涛
如大家所说,“这个问题无解,只能优化体验”,那我们就讨论“优化”吧
1.首先,得定个基线,这个基线包含:在什么网络程度用户体验流畅,什么程度上用于体验可以接收,什么程度上保持逻辑一致和稳定就够了。具体基线和网络和游戏设定有关系,建议在纸上先论证清楚。我们这里主要讨论网络,可以去找找网络延时得分布,我们通常得建议是,网络延时,100毫秒以内,用户体验流畅,100-200毫秒,用户体验可以接收,200-400毫秒,勉强可玩,400毫秒以上,保证稳定和一致性的前提下,尽量能玩。200毫秒能覆盖很大部分的玩家了,有了这个基线,项目组就可以进行更好的游戏设定,如果不考虑基线,这个问题真的无解。
2.每秒20帧,如果位置移动按照这个频率采样,看起来会不够流畅,一般的做法,是表现层做平滑,将时间片拆成更小的粒度,使得位置采样更密集,这样移动看起来更平滑。
3.表现层预测,如题主所说的,保持运动的惯性,第2点说了,时间片的粒度更小,那么误差的范围可能更小,设定一个容差范围,通过表现层的平滑将误差逐步修正,允许表现层位置和逻辑层位置在一定范围内不一致,这是关键,而“这个范围”就是用来“包容”网络延迟的。
4.绝对的网络延迟导致的主要是用户输入的延迟,位移的抖动更多的是网络抖动造成的,题主可以加如一些抗抖动的技巧,原理上是把时间轴上分布不均匀的信号,尽量均匀化,可以搜下jitterbuffer
邪让多杰
如果对实时性要求不是非常高的游戏,可以采用可靠UDP在客户端延迟播放帧,延迟的时间周期可以通过UDP包丢失后重传机制进行补齐后再继续播放帧。
如果对实时性要求非常高的游戏,如上通过ACK确认UDP丢包后再重传机制可能时间上来不及了,这时候直接采用双发重复发送UDP包的机制可能更好。双发会带来网络流量翻倍上升,这时候可以通过统计识别出来哪些玩家的网络好哪些玩家的网络不好,对于网络好的玩家使用正常的单发UDP包,对于网络不好的玩家才使用双发UDP包。