英文原文:
https://mirror-networking.gitbook.io/docs/components/network-discovery
假设你在一个朋友旁边。他以主持人模式开始游戏,而您想加入他。你的手机将如何定位他的?找出他的 IP 地址并不是很直观,也不是孩子们可以做的事情。
要解决此问题,您可以使用Network Discovery。当您的游戏开始时,它会在您当前的网络中发送一条消息,询问“是否有可用的服务器?”。同一网络内的任何服务器都会回复并提供有关如何连接到它的信息。
Mirror 附带了一个简单的网络发现实现,您可以在游戏中简单地使用它。它还为您提供了一种扩展它的方法,以便您可以在发现阶段传递其他数据。
包括 NetworkDiscovery 和 NetworkDiscoveryHUD 组件,或者您可以从 ScriptTemplate 制作自己的组件。
NetworkDiscovery 使用 LAN 上的 UDP 广播,使客户端能够找到正在运行的服务器并连接到它。
当服务器启动时,它会在 UDP 广播侦听端口上侦听来自客户端的请求,并返回客户端应用于其传输的连接 URI。
您可以使用 Active Discovery Interval 调整客户端发送请求以在几秒钟内找到服务器的频率。
必须将 Server Found 事件分配给处理程序方法,例如NetworkDiscoveryHUD 的 OnDiscoveredServer 方法。
在 NetworkDiscoveryHUD 中,应自动分配 NetworkDiscovery 组件。
快速入门
要使用网络发现,请执行以下步骤:
- 如果您还没有这样做,请使用 NetworkManager 创建一个游戏对象
- 不要添加 NetworkManagerHUD。 Discovery 具有不同的 UI 组件。
- 将 NetworkDiscoveryHUD 组件添加到 NetworkManager 游戏对象。NetworkDiscovery 组件将自动添加并连接到您的 HUD。
- 如果您还没有这样做,请将Player添加到 NetworkManager。
- 构建并运行独立版本
- 点击启动Host
- 在编辑器中启动播放模式,然后单击 Find Servers
- 编辑器应该找到独立版本并显示一个按钮
- 单击按钮以连接到它。
NetworkDiscoveryHUD 是作为一种简单快捷的入门方式提供的,但您可能希望将其替换为您自己的用户界面。
自定义Network Discovery
您可以通过添加自己的界面(通常基于 Unity UI)而不是默认的 NetworkDiscoveryHUD 来完全替换用户界面。您仍然需要 NetworkDiscovery 组件来完成繁重的工作。
有时您想在发现消息中提供更多信息。一些用例可能包括:
- 客户端可以显示服务器是处于 PvP 还是 PvE 模式
- 客户端可以显示服务器有多满。
- 客户端可以向每个服务器显示 ping,因此玩家可以选择最快的服务器
- 客户端可以显示语言
- 客户端可以显示服务器是否受密码保护
为此,我们提供了一个模板,因此从资产菜单中,单击Create > Mirror > Network Discovery.
这将在您的项目中创建一个脚本,其中包含 2 个空消息类和一个自定义 NetworkDiscovery 类,该类继承自 NetworkDiscoveryBase 并包含所有覆盖方法并为您记录。
消息类定义客户端和服务器之间发送的内容。只要您使用 Mirror 可以序列化的数据类型使您的消息保持简单,您就不需要为它们编写自定义序列化程序。
public class DiscoveryRequest : MessageBase
{
public string language="en";
// 为您希望客户端发送的任何信息添加属性
// 在服务器将使用的广播消息中。
}
public class DiscoveryResponse : MessageBase
{
enum GameMode {PvP, PvE};
// 你可能需要URI,以便客户知道如何连接到服务器。
public Uri uri;
public GameMode GameMode;
public int TotalPlayers;
public int HostPlayerName;
// 为您希望服务器返回的任何信息添加属性
// 客户端供他们显示或使用以建立连接。
}
自定义 NetworkDiscovery 类包含用于处理上述消息的覆盖。
您可能需要参考 Components/Discovery 文件夹中的 NetworkDiscovery.cs 脚本来了解如何实现这些。
public class NewNetworkDiscovery: NetworkDiscoveryBase
{
#region Server
protected override void ProcessClientRequest(DiscoveryRequest request, IPEndPoint endpoint)
{
base.ProcessClientRequest(request, endpoint);
}
protected override DiscoveryResponse ProcessRequest(DiscoveryRequest request, IPEndPoint endpoint)
{
// TODO: Create your response and return it
return new DiscoveryResponse();
}
#endregion
#region Client
protected override DiscoveryRequest GetRequest()
{
return new DiscoveryRequest();
}
protected override void ProcessResponse(DiscoveryResponse response, IPEndPoint endpoint)
{
// TODO: a server replied, do something with the response such as invoking a unityevent
}
#endregion
}