从 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 相关的类。