Version: 2021.2
高级状态同步
自定义网络可见性

网络可见性

Important: UNet is a deprecated solution, and a new Multiplayer and Networking Solution (Netcode for GameObjects) is under development. For more information and next steps see the information on the Unity Netcode for GameObjects website.

多人游戏使用网络可见性的概念来确定哪些玩家可以在游戏过程中的任何给定时间查看哪些游戏对象。在具有移动视点和移动游戏对象的游戏中,玩家通常并不能立即看到游戏中发生的所有事情。

如果特定玩家在游戏过程中的某个时间点不能看到游戏中的大多数其他玩家、非玩家角色或者其他移动或互动元素,则主机通常无需向该玩家的客户端发送有关这些元素的信息。

这可以在两个方面让游戏受益:

  • 减少了玩家之间通过网络发送的数据量。这样便有助于提高游戏的响应能力,并减少带宽使用。多人游戏越大越复杂,这个问题就越重要。

  • 还有助于防止黑客入侵。由于玩家客户端没有关于无法看到的元素的信息,因此该玩家的计算机受到黑客攻击时不会暴露这些信息。

网络上下文中的“可见性”概念并不一定与游戏对象是否在屏幕上直接可见有关。实际上,此概念涉及是否应该将有关游戏对象的数据发送给特定客户端。简而言之,如果客户端无法“看到”游戏对象,则无需通过网络发送有关该游戏对象的信息。理想情况下,通过网络发送的数据量应仅限于必要数据量,因为通过网络发送大量不必要的数据可能会导致网络性能问题。

然而,准确地确定游戏对象是否对给定玩家真正可见也可能是资源密集型或复杂的过程,因此通常最好能使用较简单的计算方式来确定是否应该向玩家发送该游戏对象的相关网络数据(即,该游戏对象是否“在网络上可见”)。在考虑这一点时,需要权衡确定可见性的计算的复杂性成本与在网络上发送超过必要量的信息的成本。一种非常简单的计算方式是距离(接近度)检查,Unity 为此提供了一个内置组件。

Network Proximity Checker 组件

Unity 的 Network Proximity Checker 组件是为玩家实现网络可见性的最简单方式。该组件与物理系统协同工作,确定游戏对象是否足够接近(即在多人游戏中是否“可见”,如果可见,则需要发送网络消息)。

Network Proximity Checker 组件
Network Proximity Checker 组件

要使用此组件,请将其添加到要限制网络可见性的联网游戏对象的预制件。

Network Proximity Checker 具有两个可配置的可见性参数:

  • Vis Range 控制着网络应将游戏对象视为对玩家可见的距离阈值。

  • Vis Update Interval 控制着距离测试的执行频率。该值是检查之间的延迟(以秒为单位)。此设置可用于优化检查以执行尽可能少的测试。数字越小,更新发生的频率越高。对于缓慢移动的游戏对象,可将此间隔设置为较高的值。对于快速移动的游戏对象,应将其设置为较低的值。

必须将碰撞体 (Collider) 组件附加到要与 Network Proximity Checker 一起使用的所有游戏对象。

远程客户端上的网络可见性

当远程客户端上的玩家加入联网游戏时,只有该玩家在网络上可以看见的游戏对象才会在该远程客户端上生成。因此,即使玩家进入一个拥有大量联网游戏对象的大型世界,游戏也可以快速启动,因为不需要生成世界中存在的每个游戏对象。请注意,这一情况适用于场景中的联网游戏对象,但不影响资源的加载。Unity 仍然需要时间来加载已注册的预制件和场景游戏对象的资源。

玩家在世界范围内移动时,具有网络可见性的游戏对象集合会发生变化。发生这些变化时,玩家的客户会被告知这些变化。游戏对象不再具有网络可见性时,ObjectHide** **消息将发送到客户端。默认情况下,Unity 在收到此消息时会销毁该游戏对象。游戏对象变得可见时,客户端会收到 ObjectSpawn 消息,就像 Unity 第一次生成游戏对象一样。默认情况下,该游戏对象就像任何其他生成的游戏对象一样进行实例化。

主机上的网络可见性

主机与服务器共享相同的场景,因为主机同时充当托管游戏的玩家的服务器和客户端。因此,不能销毁对本地玩家不可见的游戏对象。

实际上,在调用的 NetworkBehaviour 类上有虚拟方法 OnSetLocalVisibility。在主机上更改可见性状态的游戏对象上的所有 NetworkBehaviour 脚本上都会调用此方法。

OnSetLocalVisibility 的默认实现会禁用或启用游戏对象上的所有渲染器 (Renderer) 组件。如果要自定义此实现,可重写脚本中的方法,并提供新行为来说明当游戏对象变为网络可见或不可见(例如禁用 HUD 元素或渲染器)时主机(也就是本地客户端)应如何响应。

高级状态同步
自定义网络可见性