[Unity Mirror] FAQ

如何发送/同步自定义数据类型?

  Mirror 可以在编译脚本时自动为许多自定义数据类型创建序列化函数。

  例如,mirror 会自动为 MyCustomStruct 创建一个函数,以便无需任何额外工作即可发送它。

[ClientRpc]
public void RpcDoSomething(MyCustomStruct data)
{
    // do stuff here
}

struct MyCustomStruct
{
    int someNumber;
    Vector3 somePosition;
}

更多细节

  • Data Types
  • Serialization

如何连接到另一个 Mirror 实例?

到同一设备上的另一个实例

  确保您连接到“localhost”。本地主机基本上意味着“本地主机”,即您的本地机器。

  确保 NetworkManager 上的网络地址字段设置为“localhost”,或者如果使用 NetworkManagerHUD,则文本框为“localhost”。确保不包括引号。

  请注意,这不适用于移动设备,因为 iOS 或 Android 都不支持并排运行同一应用程序的两个实例。这更适合桌面测试和开发使用。

到同一网络 (LAN) 上的另一个实例

  确保 NetworkManager 上的网络地址字段设置为主机的 LAN IP,或者如果使用 NetworkManagerHUD,则将文本框设置为主机的 LAN IP。

  例如,正确的设置是“192.168.8.100”、“10.0.0.100”、“172.16.42.69”
例如,不正确的设置是“localhost”或“203.200.110.100”

  在某些情况下,您可能需要额外的步骤,请查看以下内容

  要在 Windows 上检查 LAN IP,您可以打开 PowerShell/命令提示符并使用 ipconfig 命令,然后在当前适配器(以太网/wifi/等)下查找 IPv4 地址条目,如下所示:

IPv4 Address. . . . . . . . . . . : 192.168.x.x

  在 Mac OS 上,您可以在设置应用程序中使用网络设置,而在 Linux 上,您可以使用 ifconfig、ip addr 或像 NetworkManager 或 wicd 这样的 GUI 来获取您的 LAN IP,具体取决于您是在运行桌面环境还是在命令行。

到另一个实例 (Internet/WAN)

  将 networkAddress 字段设置为主机的 IP 地址(google ‘whats my IP’)

本节不包括中继、专用 VPS 或Headless 功能。

  为此,您需要执行以下一些操作,其中大部分取决于您的设置和路由器:

  • 转发端口
    • 确保您的 ISP 允许您在自己的连接上托管服务器,一些 ISP 不允许这样做并且会过滤传入连接。如有疑问,请咨询您的 ISP。知识就是力量。
    • 确保您的 ISP 允许您更改路由器上的设置。有些可能非常严格并重置您随机更改的设置。
    • 将您的游戏端口(默认为 7777)转发到 PC 的本地 IP,例如 192.168.1.20。确保您指定了正确的协议,如果您将其设置为仅接受传入的 TCP 连接,传入的 UDP 连接将不起作用,反之亦然。如果你的路由器支持,你可以使用“BOTH”设置来绕过这个头疼的问题;或者
    • 拉一个快速(但不太安全)的技巧将本地 IP 添加到路由器的 DMZ 以采取绝望的措施。

DMZ 可能是一个非常有用的工具,但请注意:能力越大,责任越大!
具有您指定的 IP 地址的计算机将在 Internet 上公开,而路由器防火墙不会过滤不良的入站流量。这意味着,如果您正在运行任何私有 Web 服务器或应用程序,您可能会受到位于 Internet 上其他位置的其他人的入侵。

如果您运行的是未打补丁的操作系统(例如,旧版本的 Microsoft Windows)或您的计算机安全受到威胁,请勿使用此 DMZ 选项。在使用 DMZ 设置之前,请确保您的安全已启用并且您的防病毒/反恶意软件已完全更新。

  • 电脑防火墙:
    • 您可以将其关闭以进行快速测试,以查看您的防火墙是否令人讨厌。确保稍后重新打开它。
    • 手动允许编辑器和您在防火墙设置中创建的任何构建。
  • 尝试从Build而不是 Unity 编辑器,因为有时 Unity 编辑器可能会很卡。
  • 一些防病毒/移动设备可能有额外的阻止层:
    • 如果可以,请尝试关闭它们以进行快速测试。确保稍后重新打开它。
  • 在极少数情况下,ISP 或公司/学校会阻止端口和连接,这很难自行调整。

  如果您需要更多帮助,最好在谷歌上搜索您的设置和路由器指南。一个可靠的替代方案是使用专用服务器/VPS 或使用中继。


主机迁移

主机迁移替代方案和解决方法。

  在撰写本文时,主机迁移并未内置在 Mirror 中,如果可以的话,最好完全避免主机迁移。下面是一些关于为什么以及如何添加类似主机迁移的替代方案的提示。

  • 如果您正在做需要保持开放的游戏,例如 MMO,专用主机应该很少关闭。
  • 简短的竞技场地图,将玩家带回游戏列表/匹配器,这样他们就可以加入另一个,漂亮而简单。

  解决方法基本上是伪造主机迁移,将备份主机的信息存储在玩家游戏中,断开连接后,将游戏中的每个人重新连接到该新主机,然后将位置和变量数据恢复到原始主机消失之前的状态。

  • 在玩家加入时测试他们的连接,找到一个端口畅通且 ping/延迟不错的连接。
  • 在所有连接的玩家游戏中发送此玩家数据(IP 和端口)。
  • 在本地或备份主机上保存各种玩家信息,例如玩家位置、健康状况等。
  • 与服务器断开连接后,调用函数连接到备份主机。例如,StartClient( BackupIP - BackupPort )
  • 由于场景很可能会随着玩家重新生成而重置,因此您现在需要将玩家位置设置回您存储的位置,该位置通过检查点或在断开连接检测回调中保存。
  • 用 UI 覆盖所有这些,说请稍候(可选,应该在眨眼间发生)。

根据您的游戏情况,添加变通方法可能容易或困难。其中的一个例子是:

  • (更简单)只需要玩家位置数据的游戏,例如“Fall Guys”。
  • (困难)帝国锻造,一个放置创建对象的游戏,士兵,车辆,各种其他工艺和升级,都有自己的等级/统计数据。

主服务器/列表服务器和简单的匹配器

全球注册主机数据的数据库

  所有主机,专用主机或玩家主机,都被添加到列表数据库中,玩家获取列表并可以选择加入谁。使用列表服务器意味着玩家不必手动输入 IP 地址和端口,这一切都在幕后完成,适用于 localhost、LAN 和 WAN 连接类型。您可以向玩家显示尽可能多或尽可能少的数据,例如主机名、类型(死亡竞赛)、玩家数量(45 / 50)、ping、敌人难度、地图、区域等。

  • Node ListServer:免费,但您自己将文件托管在未受阻的 PC 上,例如 VPS。具有多种可定制功能,如果您想要自托管专用游戏,是最佳选择。

  • Light Reflective Mirror:这是一个列表服务器和一个中继,它是免费的,但您自己托管和管理文件。中继提供畅通的流量路由,但代价是额外的延迟/增加的 ping。此中继将首先测试直接连接,如果失败则回退到路由流量。列表服务器和中继流量都是可选的,您可以使用其中的一部分,而不能使用另一部分。这是玩家托管游戏的最佳选择,其中路由器端口块很常见。

  • Epic 和 Steam,这些都是为您托管的。
    查看 Discords 插件和传输部分以获取更多信息,以及其他未列出的配对和列表服务器方式。

简单的匹配器

  • 你可以把这些列表服务器做成匹配器,简单地把列表隐藏给玩家,让他们自动加入一个有空间的游戏。你也可以过滤掉玩家设置的各种要求,例如,只限于 "美国 "地区,或 "熔岩岛 "地图。

如何获取玩家数量?

有几种方法可以做到这一点,每种方法都有自己独特的好处。

NetworkServer.connections.Count

  • 套接字连接,包括没有生成prefab、未经过身份验证的人,或者可能在生成过程中出错但临时连接的人(Android 用户最小化游戏)。只有主机/服务器可以检查这个。

NetworkManager.singleton.numPlayers

  • 服务器上活跃已经生成的玩家对象的数量(只有主机/服务器可以检查这个)

按GameObject Tag查找

  • 在客户端工作,不需要网络代码,并且是区分玩家状态的好方法,通过在某些情况下应用游戏对象标签,例如,“未准备好/默认”、“死亡”、“观众”。
public GameObject[] playersArray;

public void FindPlayersByTag()
{
  playersArray = GameObject.FindGameObjectsWithTag("Player");
   Debug.Log("Players found: " + playersArray.Length);
}

你可能感兴趣的:(Unity,Mirror,unity,网络,Mirror)