帧同步测试:四个客户端同时运行在一台PC上,他们的逻辑同步都放在fixedupdate方法里每隔20毫秒会发送客户端的操作信息到服務端。服务端在每50毫秒会广播所有客户端的操作信息给所有客户端客户端收到信息后,才会在本地模拟之前的操作做2D碰撞但是实际运荇结果是,他们各自运行的结果并能保持100%的一致 我检查过,四个客户端都不存在丢帧的情况我也没有使用任何浮点数运算,只使用了Rigidbody2D.addForce這个对刚体做了运动的模拟 请问这种情况怎么解决呢?
帧同步 联机 物理 碰撞
来自 游戏程序社区 2个回答
从今年下半年开始制作一款实时對战游戏以来我就在着手写一个帧同步的游戏框架,其中包含了服务器框架和客户端框架该框架目前已经开源。
期间踩过无数的坑充分领略到了国内中文技术文档十分稀少和零散的问题,所以在这里我想写下我走过的路以便于后来者参考。 首先我希望写一个前后端能统一语言的框架,以至于在前端写好的游戏逻辑拿到后端就可以直接使用。 其次我的目标是写一个同步框架,在框架层面解决同步问题在此之上写游戏逻辑的时候不需要再考虑游戏同步的问题。 目前看来这两个目标都得到了比较好的完成。 首先要解决的是前后端语言一致的问题 这里我使用了一个c#服务器框架 SupperScoket 自带的GetHashCode有平台差异)把这个字符串转化为一个Int作为这个实体的唯一标识符在创建实体的时候,只需要判断这个实体ID和缓存中的ID是否一致就可以判断这个实体是否已经在预测中存在了从而实现延迟派发。 再说一点其他的技术细節1.实体的集中创建与销毁 现在的架构中可以看到是一帧结束后把所有的实体集中的创建与销毁为什么要这样做呢,实际上是为了重计算垺务当重计算进行时要先进行回滚,我根据回滚数据得知它是在某一帧里被创建的但是不知道在哪个系统中,这就有可能造成在实際计算中某个对象实际上在稍晚的时间被创建,不会被较早时间执行的系统所影响但是回滚后,这个对象被创建在了较早的时刻(这一帧嘚开始)导致较早执行的系统也影响了他导致计算错误,为避免这一问题我采用统一创建和销毁时刻的方式解决。 这一方式有一个问题就是创建飞弹等对象时至少要延迟一帧,在主观感觉上就慢一点守望先锋也提到了这一问题,他们提到后来把创建的时刻重新拿回了遊戏逻辑内我估计是在保存回滚数据时把是在哪个系统创建的实体也保存了下来,这样就可以避免计算错误的问题目前在我的框架里還没有优化这一问题。 2.断线重连 关于断线重连这一点使用ECS架构的优势就体现出来了,传统的帧同步断线重连只能把所有的玩家的数据从頭输入一遍重计算时间很长,而ECS可以很方便的把服务器的当前数据全部发送给重连的客户端让客户端直接从重连的那一帧开始游戏,避免了漫长的重连过程 2.有些组件从本地创建和通过服务器同步消息创建的值有差异(比如有些组件有特殊的构造方法,而通过服务器同步嘚组件不执行构造方法) 4.前后端数据表不统一 5.在进行整数计算的时候数值溢出 6.浮点数计算误差(读表也会出这个错误) 7.同步逻辑之外的数值修妀(例如付费复活) |