从 UNet (HLAPI) 迁移项目

  本指南为您提供将项目从 UNET 迁移到 Mirror 的分步说明。 Mirror 是 UNET 的一个分支。因此,对于大多数项目来说,迁移是直截了当的。

  您应该查看弃用页面上的信息,看看您的项目是否会受到影响。

  您还可以尝试使用迁移工具

1. 备份

你已经被警告过了。

2. 安装Mirror并重启 Unity

  从 Asset Store 获取 Mirror 并将其导入您的项目中。

  或者,如果您喜欢冒险,您可以从 GitHub 获取最新版本,但请注意,最前沿的开发版本不一定稳定。

  注意:您必须在将 Mirror 添加到项目后重新启动 Unity,才能正确更新组件菜单。

3.替换命名空间

  将 UnityEngine.Networking 替换为项目中任何地方的Mirror。例如,如果你有这个:

using UnityEngine.Networking;

public class Player : NetworkBehaviour
{
    ...
}

将其替换为:

using Mirror;

public class Player : NetworkBehaviour
{
    ...
}

此时,您可能会遇到一些编译错误。不要惊慌,这些很容易解决。继续前进…

4.用identity替换playerController

  用 NetworkConnection.identity 替换对 NetworkConnection.playerController 的引用。

5.删除NetworkSettings

  UNet 中的 NetworkSettings 有通道,但这完全被打破了。我们没有忽略您的设置,而是完全从 NetworkSettings 中删除了通道。 sendInterval 现在也在代码和/或 inspector 中设置。
  例如,如果您有以下代码:

[NetworkSettings(channel=1,sendInterval=0.05f)]
public class NetStreamer : NetworkBehaviour
{
    ...
}

将其替换为:

public class NetStreamer : NetworkBehaviour
{
    void Start()
    {
        syncInterval = 0.05f;
    }
}

  请注意,默认传输Telepathy,完全忽略通道,所有消息都是可靠的、有序的和碎片化的。他们只是毫不费力地工作。如果您想利用不可靠的渠道,请尝试使用 UDP 或 Steam 传输。

6. 将 SyncListStruct 更改为 SyncList

  原始 UNet Weaver 中存在一个错误,导致它在不检查命名空间的情况下与我们的 Mirror.SyncListStruct 混淆。在 Mirror 中,我们修复了 SyncLists,以便它们默认使用structs。

  例如,如果您有如下定义:

public class SyncListQuest : SyncListStruct {}

将它们替换为:

public class SyncListQuest : SyncList {}

7. 替换 NetworkHash128 和 NetworkInstanceId

  这些已分别更改为 System.Guid 和 uint。

例如,如果你有这样的东西:

public sealed class SpawnItemMessage : MessageBase
{
    public NetworkHash128 assetID;
    public NetworkInstanceId networkInstanceID;
    public Vector3 position;
    public Quaternion rotation;
}

将它们替换为:

public sealed struct SpawnItemMessage : NetworkMessage
{
    public System.Guid assetID;
    public uint networkInstanceID;
    public Vector3 position;
    public Quaternion rotation;
}

8. 更新你的 SyncList 回调

  在 UNet 中,SyncLists 有一个回调委托,只要列表更新,就会在客户端中调用该委托。我们已将回调更改为 C# 事件,并且我们还传递了已更新/删除的item。

例如,如果您有以下代码:

using UnityEngine;
using UnityEngine.Networking;

public  class MyBehaviour : NetworkBehaviour
{
    public SyncListInt m_ints = new SyncListInt();

    private void OnIntChanged(SyncListInt.Operation op, int index)
    {
        Debug.Log("list changed " + op);
    }

    public override void OnStartClient()
    {
        m_ints.Callback = OnIntChanged;
    }
}

将其替换为:

using UnityEngine;
using Mirror;

public  class MyBehaviour : NetworkBehaviour
{
    public SyncListInt m_ints = new SyncListInt();

    private void OnIntChanged(SyncListInt.Operation op, int index, int oldItem, int newItem)
    {
        Debug.Log("list changed " + op + " old item: " + item + " new item: " + newItem);
    }

    public override void OnStartClient()
    {
        m_ints.Callback += OnIntChanged;
    }
}

  请注意,回调也将在 Mirror 中的server中工作。

9. 更换组件

  每个联网的预制件和场景对象都需要调整。他们将使用 Unet 中的 NetworkIdentity,您需要使用 Mirror 中的 NetworkIdentity 替换该组件。您可能正在使用其他网络组件,例如 NetworkAnimator 或 NetworkTransform。 Unet 中的所有组件都应替换为 Mirror 中的相应组件。

  请注意,如果您删除并添加 NetworkIdentity,则需要在引用它的任何组件中重新分配它。

10. Update扩展组件

  一些常用的扩展组件,例如 NetworkManager,在 Mirror 中改变了方法参数。一个常用的override是 OnServerAddPlayer。使用原始 HLAPI,您的override可能看起来像这样:

public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId, NetworkReader extraMessageReader)
{
    base.OnServerAddPlayer(conn, playerControllerId, extraMessageReader);
    // your code
}

  在新的支持Mirror的 NetworkManager 中,如果您使用 OnServerAddPlayer 覆盖,请从覆盖和基本调用中删除“playerControllerId”和“extraMessageReader”参数:

public override void OnServerAddPlayer(NetworkConnection conn)
{
    base.OnServerAddPlayer(conn);
    // your code
}

  有关如何立即提交自定义角色的详细信息,请参阅自定义玩家生成指南。

11. 选择你的传输方式

  您可以在 Mirror 中选择多种传输方式之一。打开您的 NetworkManager 游戏对象,在检查器中您将默认看到 TelepathyTransport 组件。如果您希望改用基于 UDP 的传输,则拖入其中一种可用的传输并删除 TelepathyTransport。

12.配置地址和端口

  在 HLAPI 中,您可以在 NetworkManager 中配置端口和本地地址。我们的目标之一是使Mirror传输独立。并非所有传输都需要地址和端口。一些传输甚至可能同时使用多个端口,因此这些设置是不充分的。我们从 NetworkManager 中删除了端口和地址以及所有其他网络信息属性,并将它们移至传输组件。

13.更新你的防火墙和路由器

LLAPI 使用 UDP。Mirror默认使用 TCP。这意味着您可能需要更改计算机中的路由器端口转发和防火墙规则,以公开 TCP 端口而不是 UDP。这在很大程度上取决于您的路由器和操作系统。

可能的错误信息

  • TypeLoadException:发生了类型加载异常。 - 如果您的项目中仍有 SyncListStruct 而不是 SyncListSTRUCT,则会发生这种情况。
  • NullPointerException:最可能的原因是您替换了 NetworkIdentities 或其他组件,但您将它们分配到了某个地方。重新分配这些引用。
  • 错误 CS0246:找不到类型或命名空间名称“UnityWebRequest”。您是否缺少使用指令的“UnityEngine.Networking”?
    将此添加到脚本的顶部:
using UnityWebRequest = UnityEngine.Networking.UnityWebRequest;

  UnityWebRequest 不是 UNet 或 Mirror 的一部分,但它与 UNet 位于同一命名空间中。将命名空间更改为 Mirror 会导致您的脚本找不到 UnityWebRequest。这同样适用于 WWW 和所有 UnityWebRequest 相关的类。