请问各位大佬们,帧同步一般怎么做?
我这边使用的websocket,需要同步移动、移动状态;
使用摇杆或物理移动来处理移动,如果是物理,触摸的时候线行速度是10,是同步线性速度还是同步坐标?
如果要躲避障碍物,是用刚体还是用什么?
同步请求多久发一次,0.2秒还是0.5秒?
请问有大佬清楚么?
渣渣路过,简单分享一下我的看法。
1、帧同步里的帧渲染、移动、碰撞需要在同一帧中去渲染。例如客户端收到1帧数据,那么A玩家就得在这帧数据中移动5像素,然后同时检测是否与其他物体产生碰撞。
2、逻辑帧与渲染帧分开,比较常见的是逻辑帧10-30帧/秒 ,这个是服务端主动推的频率,渲染帧根据逻辑帧最新数据去更新数据,例如xyz
3、搞定固定帧、定点数,这个避免不了。
4、websocket基于tcp ,可能会存在一些延迟性的问题。看业务需求是否换个协议,例如udp
5、帧同步,同步的是操作。而不是坐标,不然那就是状态同步。
还得优化数据传输的字节大小,一定得要二进制传输,不然会影响带宽以及传输速度
那如果是状态同步,请问怎么弄呢?
自己计算好要操作的数据,给服务器广播给其他用户就好了。也可以让服务器来做逻辑,统一转发
一个即时的游戏,行走用帧同步比较好吧?要同步行走的状态、和摇杆角度以及移速么?那这个时候是每帧向服务器进行请求么?
这位大佬回答差不多了,建议楼主你自己先动手去摸索、尝试一下
对帧同步,有些疑惑,就是逻辑帧和 渲染帧的插值是怎么搞的 :假设逻辑帧是每秒20,渲染帧是每秒60,逻辑帧去执行移动逻辑: 3秒 移动了一百, 然后渲染帧 去执行动作:cc.moveTo(100,3) ,假设渲染帧是90帧,那我还是得执行cc.moveTo(100,3) 啊,这个插值的体现在那?不太懂这方面 ,还是我的构想 一开始就错的
移动逻辑应该在update方法中去处理,无需理会到底是60或者90 ,利用好dt就行
不需要理会渲染帧率是 60, 90 还是120么?是什么原理? 我看教程人家说要有个逻辑帧和渲染的换算什么的, 还有,除了移动这种场景,释放技能,播放动画的场景呢?也不需要理会当前渲染帧率?直接播?
好一点的手机60、90、120渲染帧,低端机10~30帧,这种情况都会有,客户端很难避免这种情况,比较依赖update的dt来控制移动数据,60帧的话, dt=(1/60=0.01666 ) ,120帧的dt就等于 1 / 120 ,以此类推。
做移动计算的时候,都需要靠dt的值来做递增
你的逻辑对于帧同步是错的,帧同步是渲染帧推动本地逻辑帧,如果本地逻辑帧落后服务器逻辑帧则执行追帧,相当于1帧执行n帧的逻辑
是这样的,用状态帧同步结合起来。客户端和服务器同时维护一个120帧的循环,如果有客户端触摸了摇杆,客户端先不移动,而是发送当前移动的归一化方向向量(或者你也可以理解为前进方向)给服务器。
现在重点来了:
1.客户端怎么循环发送
2.服务器怎么循环广播
答案:
1.客户端固定120帧FixUpdated(每帧理论经过8.8ms进行检测),逻辑是检测当前摇杆是否被按下,但是不移动,只获取摇杆方向向量。只获取摇杆方向向量。只获取摇杆方向向量。
重点:(1)角色当前在墙边,而你这一帧如果按下摇杆,也就是说如果你的方向向量在这一帧FixUpdated与墙的夹角或者说是撞墙或者擦墙的移动角度,那么要将方向向量再重新数学计算赋值为平行于墙的归一化方向向量(往前还是往后取决于夹角角度),否则,正常计算摇杆当前的方向向量。(王者荣耀和英雄联盟手游,你贴的墙走的那种感觉)。
(2)客户端根据当前方向向量,然后立即将当前方向向量发送给服务器。重中之中!重中之中!重中之中!你一定要用服务器计算新坐标位置,而不是用客户端!
(3)客户端也使用事件触发的方式,回调网络同步方法,在update中更新所有客户端坐标包括自己(服务器下面会说)
2.服务器120帧。分为A触发器和N个触发器(强烈建议都设置为有缓存通道)
怎么做:前提提醒:服务器每1帧发送的是所有人的坐标,在1个客户端的视角来看:客户端这1帧接收到了所有人的坐标。
(1)服务器维护1个每秒发送(或者说执行)120次的有缓冲的事件通道(命名A)(8.8ms),(你可以用服务器各种包或者github上找下定时器缓冲channel这类东西),也就是说,这个触发器固定1秒执行120次(可能会有波动)
(2)服务器还需要维护N个事件触发器(或者说就是channel通道触发器,主动发送信息到通道或者说主动执行才会触发回调)。
----将A固定缓冲事件触发器和N个主动事件触发器一起维护起来,构成服务器游戏状态帧同步逻辑。
做什么:
(1)A:每1帧根据客户端方向向量计算新坐标并存储,然后立即分发广播同步所有人的位置坐标。
(2)N:
-------方向向量触发器:如果接收到任意客户端的新方向向量,立即存储更新服务器方向向量
-------技能触发器:如果接收到任意客户端的释放技能的请求,立即执行技能逻辑,主要是马上用服务器当前存储的位置信息进行判断,比如拉克丝的大招,服务器已经存储当前客户端起点,客户端给了大招释放方向,服务器再计算长度和覆盖的区域,这个涉及到数学相交的逻辑自己去学下。(注意:技能触发器等统称为状态触发器,是跟A触发器分开的,只要N触发了各类事件立即计算对应状态然后立即分发所有人,不需要像A触发器那样有帧间隔等待时间,换句话说A触发器只是一个固定时间间隔计算同步分发位置的触发器,而且是雷打不动的)
-------各种血量蓝量触发器,不多说了,你可以合并一些功能相似的触发器。
下面说下可能是问题的问题:客户端FixUpdated波动,正常来说很难,但是可以考虑下,向上波动(没遇到这种情况或者很难复现):120帧变成125帧,卧槽多了帧怎么办,岂不是客户端1秒发送了125次方向向量给服务器,没事的,服务器A是120帧每秒分发计算新位置,这个固定死了,多出来的5帧只是多更新了5次方向向量,而A是120帧的每帧拿到当前帧的方向向量进行计算,你可以理解为随机覆盖掉5个方向向量(因为有8.8ms的等待时间,这期间就是多余方向向量覆盖掉的时间)。向下波动:客户端120帧变成100帧,理论上,服务器1秒发送了120次,客户端1秒执行100次回调,这个回调要想让客户端在update执行,需要客户端也在生命周期脚本里写一个Channel用Update去感知Channel,在这种情况,客户端理论上有20帧执行了2次坐标同步,80帧正常执行1次坐标同步,当然也可以理解为覆盖了坐标同步,我没实践过不太确定。
服务器A波动,向上波动:服务器120帧变成了125帧,没事,如果客户端update > 125帧,理论上正常更新坐标,理论上有5帧没有执行逻辑。
如果客户端120-125,比如123,理论上有1帧更新2次位置,说实话感受不到。
客户端小于120,比如100,那么相当于1帧更新了1.25帧的位置,或者说4帧更新了5帧的位置,也就是说有1帧更新了2次位置。也就是说一共有25帧更新了2次位置,其余75帧正常更新了1次位置,感觉好像也没事,没验证过。
服务器A向下波动:120帧变110,也就是说服务器这1秒发送了110次同步。客户端如果>110,那么部分多余的update不会执行逻辑,客户端=110,正常。客户端<110,应该跟上面说的一样,1次update覆盖掉2次坐标更新。
最后一个注意的点是:客户端同步坐标的时候(在update里面的逻辑),可以直接赋值或者高速lerp一下看看效果有什么区别,因为我没试过所以还是要实际去调整。至于旋转目标建议只用lerp
当然还有一个基于时间帧同步的同步方案,我没接触过不太清楚。
先到这吧 我也打累了
帧同步是渲染帧推动本地逻辑帧? 那本地逻辑肯定快了啊,怎么办?
设计理论不会快,比如客户端一秒渲染60次,服务器一秒30帧,则渲染两次本地逻辑帧+1,当然会偶尔遇到快的或者慢的情况,快了就暂停,慢了就追帧
一般只传玩家操作,不传结果
也就是说 ,无论帧数是怎么变化,DT其实已经跟着变了,我只要适配DT就行?
是的。移动的话对xy进行累加。有些项目的帧同步只是同步一下表现信息,时不时也需要同步状态同步一下数据,有差异了就补回来。太高级了就没不是很了解了