如何在多人游戏中同步物理?
Posted
技术标签:
【中文标题】如何在多人游戏中同步物理?【英文标题】:How to sync physics in a multiplayer game? 【发布时间】:2012-01-09 14:10:51 【问题描述】:我尝试找到最好的方法来做到这一点,考虑在移动设备(3G 带宽)上使用弹丸和落块进行的轮流跨平台游戏。
我想知道一个设备(当前玩家轮到 = 服务器角色)是否可以运行物理并将一些“关键帧”数据(块的位置、方向)发送到另一个设备,它只是从当前状态插入到收到“关键帧”。 使用这种方法,我很担心需要大量数据来保证其他玩家设备上的相同视觉效果。
另一种方法应该是发送物理数据(力、加速度......)并在另一台设备上运行物理,但恐怕永远不会有相同的结果。
【问题讨论】:
如果对象具有相同的起始位置和应用相同的物理数据,对象在两个设备上的结果会不会完全相同? @Kjetil 仅当您有固定的滴答时间时。如果您更新每个图形帧上的物理,则通常不会出现这种情况。 权利抢。我不确定,但是考虑跨平台(不同架构)和浮点计算应该会出现问题,不是吗? 您可能想看看 Glenn Fiedler 为物理程序员编写的关于网络的优秀 GDC 教程(2011 和 2010)。它做得比我能回答的要好得多。 【参考方案1】:我当前的实现是这样的:
-
服务器管理物理模拟
在任何物体发生重大碰撞时,物体的绝对位置、旋转和速度/加速度/力都会发送到每个客户端。
客户端将每个对象连同它们的速度一起设置在该位置并施加必要的力。
客户端计算延迟并提前物理系统以适应延迟时间。
这对我来说效果很好。我的物理系统运行在几十个子系统(地图)上。
关于我的实现的一些关键事项:
完全忽略任何未标记为“必要”的对象。例如,响应玩家移动的污垢和灰尘颗粒或响应玩家移动的草和水。基本上是非必要的东西。
顺便说一句,所有这些都是通过 UDP 发送的。这在 TCP 上会很可怕。
【讨论】:
【参考方案2】:您需要发送绝对位置和旋转。
你是对的,如果你只派部队,那是行不通的。使这项工作成为可能,但这比仅仅发送职位要困难得多。您需要两个设备以相同的方式进行计算,因此在每一帧之前,您需要等待来自另一个设备的输入,您需要使用相同的时间步长,脚本需要以相同的顺序运行或可交换,并且您只能使用保证在两台机器上给出相同结果的 CPU 指令。
最后一个问题特别严重,因为这意味着您不能使用浮点数(浮点数/单数或双精度数)。你必须使用整数,或者滚动你自己的数字格式,所以你不能利用许多现有的工具。
许多游戏使用带有客户端预测的客户端-服务器模型。如果你的游戏是回合制的,你也许可以不使用客户端预测而侥幸逃脱。相反,您可以让客户端滞后一段时间,这样您就可以相当确定在您进行渲染时服务器的输入已经存在。只有当客户端可以做出服务器关心的更改(例如移动)时,客户端预测才重要。
【讨论】:
等待每一帧的输入,我认为你是指每一个物理帧? 我的意思是每个输入帧,它可能与物理帧是一对一的,也可能不是。让输入帧和物理帧是 1 对 1 是最简单的,但如果您愿意,您可以在每次对输入进行采样时更新物理两次。以上是关于如何在多人游戏中同步物理?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Photon Unity Network(多人游戏)在 Unity 中实时同步
如何在实时多人游戏中移动对象? (统一的 Google Play 游戏插件)