英文原文:
https://mirror-networking.gitbook.io/docs/components/network-transform/snapshot-interpolation
Mirror 的 NetworkTransform 组件使用快照插值。
如果您不熟悉该术语:快照插值通过快照进行插值,同时缓冲足够多的快照以弥补延迟、丢包和加扰等非理想网络条件。
在开发新的 NetworkTransform 组件时,我们有两个目标:
-
使其稳定: 我们需要可以被数千个项目使用而不会有任何意外的东西。主要hits已经使用镜像和制作,所以我们需要非常小心才能做到这一点。
-
使其可重复使用: NetworkTransform 是需要快照插值的众多组件之一。有人可能需要它用于 3D / 2D 刚体、角色控制器等。然而,算法总是相同的。
为了实现这两个目标,我们决定将 Snapshot Interpolation 算法拆分为一个任何人都可以使用的独立类。它是原始的 C#,完全独立于 Mirror & Unity。您可以在 Mirror、独立服务器或不同的游戏引擎中使用它。
简而言之,我们想一劳永逸地解决这个问题,所以我们有一个可以使用几十年的算法,无论使用哪种引擎。
该方法可与 kcp 相媲美,kcp 只是一种可用于所有语言和引擎的可靠性算法。对于我们的 kcp 传输,我们只需将其包装在服务器和客户端类中,然后通过 UDP socket 发送结果。
模拟与测试
快照插值很难正确。我们不仅要在两个时间线(本地和远程)上运行,我们还必须处理不利的网络条件,例如延迟峰值、数据包丢失和加扰。更糟糕的是,服务器和客户端也可能负载过重,并且有时会以明显不同的频率进行更新。
说句题外话:快照插值算法花了我们4个月的时间才得以运行。超过一半的时间花在测试和模拟上,以保证稳定性。
将 Snapshot Interpolation 开发为独立算法允许我们模拟不同的场景,甚至无需运行延迟模拟或Mirror:
- 我们可以确切地模拟,如果远程在t=5,我们在t=3,我们在t=0、1、2有三个快照,同时通过不同的插值点采样,快照插值算法的表现。
- 我们可以模拟如果某人只有两个快照,到达插值结束并且仍在等待下一个快照时会发生什么。
- 如果移动用户在 100 秒延迟后切换回游戏,我们可以模拟算法的行为。
- 我们可以模拟极差的网络条件,例如 99% 的丢包和加扰。
- 如果缓冲区太大,我们可以赶上。
- 还有很多…
结果
这只是一个计算快照和参数的问题,结果 out.intended
使用算法
请通读 Mirror 中的 SnapshotInterpolation.cs 代码以查看算法和辅助函数,然后通读 NetworkTransform 作为使用示例。
总结起来,有几个关键方面:
- Snapshot 接口:您的 RigidbodySnapshot、CharacterControllerSnapshot 等结构必须实现该接口。
- 时间缓冲区,它是一个 SortedList<timestamp, Snapshot> 缓冲区。为了方便起见,我们提供了几个辅助函数,例如 InsertIfNewEnough。
- 所有这些功能都被单元测试覆盖。
- Compute() 算法:给定快照缓冲区、时间、deltaTime 和配置参数,它会吐出下一个插值快照(如果有)。
- 该函数具有大量的测试覆盖率,实际上它可能是所有 Mirror 中测试次数最多的函数。
请务必阅读 Snapshot Interpolation 文章以了解它是如何工作的,然后查看 SnapshotInterpolation.cs 和 NetworkTransformBase.cs 以查看它的实际效果。即使使用我们提供的算法,正确理解和实施它仍然不是一个容易的话题。
注意NetworkTransform是如何在不可靠的通道上每隔一段时间发送快照的。不要只在变化时才发送,这需要了解另一端最后收到的快照(要么通过可靠的,要么用通知算法)。
请注意,NetworkTransform 发送每个sendInterval。一旦我们在镜像中实施 Bitpacking 和 Delta Compression,带宽将显着降低。
基准和结果
我们建议使用 Mirror 的 LatencySimulationTransport 自己尝试一下,例如使用我们的 Benchmark 演示。即使在较差的网络条件下,只要 bufferMultiplier 足够高,快照插值也会表现良好。
一些测试视频:
- Youtube 上的 NetworkTransform 旧与新比较(秘密项目)。
- 查看原始的 Pull Request 进度视频。您可以看到延迟、丢失和加扰是如何随着每个添加的功能逐渐解决的。
- JesusLovsYooh old vs. new NetworkTransform(看左边的构建,OG NT 是旧的,NT 2k 是新的)
https://www.youtube.com/embed/fu7w9vlG7yQ?rel=0