目录
一、插件介绍
Unity插件-Mirror使用方法(一)Mirror介绍-优快云博客
二、主要组件
Unity插件-Mirror使用方法(二)组件介绍-优快云博客
Network Manager
Unity插件-Mirror使用方法(三)组件介绍(Network Manager)-优快云博客
Network Manager HUD
Unity插件-Mirror使用方法(四)组件介绍(Network Manager HUD)-优快云博客
Network Identity
Unity插件-Mirror使用方法(五)组件介绍(Network Identity)-优快云博客
Network Transform
Unity插件-Mirror使用方法(六)组件介绍(Network Transform)-优快云博客
Network Animator
Unity插件-Mirror使用方法(七)组件介绍(Network Animator)-优快云博客
Network Behaviour
Unity插件-Mirror使用方法(八)组件介绍(Network Behaviour)-优快云博客
Network Start Position
Unity插件-Mirror使用方法(九)组件介绍(Network Start Position)-优快云博客
Network Room Manager
Unity插件-Mirror使用方法(十)组件介绍(Network Room Manager)-优快云博客
Network Room Player
Unity插件-Mirror使用方法(十一)组件介绍(Network Room Player)-优快云博客
三、Network Discovery
1、组件介绍
Network Discovery 是 Unity Mirror 中用于局域网内自动发现服务器与客户端匹配的核心组件。它允许服务器主动广播自身的存在,而客户端则监听这些广播信息,无需手动输入IP地址即可加入游戏。非常适合局域网联机游戏(如本地多人对战、合作模式)的快速匹配。
假设你正站在朋友旁边。他启动了主机模式的游戏,而你想加入。你的手机如何定位他的游戏?直接找出他的IP地址并不直观,孩子们也很难做到。
为了解决这个问题,可以使用网络发现(Network Discovery)。当你的游戏启动时,它会向当前网络广播一条消息:“有可用的服务器吗?”同一网络内的所有服务器都会响应,并告知如何连接到它们。
Mirror内置了一个简单的网络发现实现,你可以直接在游戏中使用。它还支持扩展功能,允许你在发现阶段传递额外数据。
2、核心功能
-
服务器广播
-
服务器定期向局域网发送广播包,包含IP、端口及自定义数据(如房间名、玩家数量)。
-
支持 UDP 协议,确保低延迟和高效率。
-
-
客户端监听
-
客户端监听指定端口,接收局域网内的服务器广播信息。
-
自动解析广播数据,生成可点击的服务器列表。
-
-
自定义数据扩展
-
在广播包中添加额外信息(如游戏模式、地图名称、密码保护)。
-
客户端根据自定义数据筛选服务器(如只显示“休闲模式”房间)。
-
-
跨平台支持
-
兼容 Windows、Mac、Linux、Android、iOS 等主流平台。
-
3、关键属性与配置
属性 | 说明 |
---|---|
Enable Active Discovery | 启用客户端主动发现功能,定期发送广播请求搜索服务器 |
Broadcast Address | 广播地址(留空时默认使用局域网广播地址,如 255.255.255.255 ) |
Server Broadcast Listen Port | 服务器监听的UDP端口号,用于接收客户端的发现请求 |
Active Discovery Interval | 客户端主动发送发现请求的时间间隔(单位:秒) |
Transport | 网络传输协议(需手动绑定Mirror支持的传输组件,如KCP、Telepathy等) |
On Server Found (ServerResponse) | 发现服务器时触发的事件,需绑定自定义方法处理服务器响应(如更新UI或连接操作) |
4、基础使用步骤
1. 服务器端配置
-
为服务器场景中的
NetworkManager
物体添加NetworkDiscovery
组件。 -
勾选 Use Network Manager,确保广播端口与
NetworkManager
的端口一致。 -
在服务器启动代码中启用广播:
void Start() { NetworkManager.singleton.StartServer(); NetworkDiscovery.singleton.StartDiscovery(); }
2. 客户端配置
-
在客户端场景中添加
NetworkDiscovery
组件。 -
编写监听代码并处理发现的服务器:
public class ClientDiscovery : MonoBehaviour { public Transform serverListContainer; public GameObject serverEntryPrefab; void Start() { NetworkDiscovery.singleton.OnServerFound.AddListener(OnServerFound); NetworkDiscovery.singleton.StartDiscovery(); } void OnServerFound(DiscoveryResponse response) { // 实例化服务器列表项 GameObject entry = Instantiate(serverEntryPrefab, serverListContainer); entry.GetComponent<ServerEntry>().Setup(response); } }
5、代码示例
1. 自定义广播数据
using UnityEngine;
using Mirror;
// 继承自 DiscoveryRequest 和 DiscoveryResponse
public class CustomDiscovery : NetworkDiscoveryBase<DiscoveryRequest, DiscoveryResponse> {
// 服务器发送广播数据
protected override DiscoveryRequest GetRequest() => new DiscoveryRequest {
gameName = "MyGame",
playerCount = NetworkServer.connections.Count,
mapName = "Forest"
};
// 客户端处理接收到的广播
protected override void ProcessResponse(DiscoveryResponse response, IPEndPoint endpoint) {
Debug.Log($"发现服务器: {response.gameName}, 玩家数: {response.playerCount}");
}
}
// 自定义数据结构
[System.Serializable]
public class DiscoveryRequest {
public string gameName;
public int playerCount;
public string mapName;
}
public class DiscoveryResponse : DiscoveryRequest {
public string ipAddress;
public int port;
}
2. 客户端加入服务器
public class ServerEntry : MonoBehaviour {
private DiscoveryResponse serverInfo;
public void Setup(DiscoveryResponse info) {
serverInfo = info;
GetComponentInChildren<Text>().text = $"{info.gameName} ({info.playerCount}/4)";
}
public void OnJoinButtonClick() {
NetworkManager.singleton.networkAddress = serverInfo.ipAddress;
NetworkManager.singleton.StartClient();
}
}
6、高级功能与场景
1. 密码保护房间
-
服务器广播:在广播数据中添加
hasPassword
字段。 -
客户端筛选:仅显示无密码或输入正确密码的房间。
-
加入验证:客户端连接后发送密码,服务器验证后允许加入。
2. 跨局域网发现(需中继)
-
结合 NAT穿透 或 中继服务器(如 Steam Relay、Photon Cloud)实现广域网发现。
-
示例:通过中继服务器转发广播包:
void Start() { if (isServer) { RelayClient.SendBroadcastToRelay(serverData); } else { RelayClient.StartListening(OnRelayBroadcastReceived); } }
3. 动态端口分配
-
避免端口冲突,允许服务器随机选择端口并广播:
void StartServer() { NetworkManager.singleton.serverPort = 0; // 自动分配端口 NetworkManager.singleton.StartServer(); NetworkDiscovery.singleton.broadcastPort = NetworkManager.singleton.serverPort; NetworkDiscovery.singleton.StartDiscovery(); }
7、常见问题与解决
问题 | 解决方案 |
---|---|
客户端未发现服务器 | 检查防火墙是否放行UDP端口,确保服务器和客户端在同一局域网。 |
广播数据不更新 | 确认服务器更新广播数据后重新调用 StartDiscovery() 。 |
多网卡环境失效 | 在代码中指定广播使用的网络接口(如 NetworkDiscovery.useNetworkManager = false )。 |
移动端无法使用 | Android/iOS 需添加网络权限,确保应用有局域网访问权限。 |