Unity Mirror与FizzySteamworks:NetworkManager仅在Game场景生成玩家预制体
解决Mirror中仅在Game场景生成玩家预制体的问题
针对你的需求,这里提供几种直接可行的解决方案,都是基于Mirror核心逻辑的修改:
方法1:重写NetworkManager的玩家生成逻辑
自定义NetworkManager子类,通过重写OnServerAddPlayer方法,根据当前场景判断是否生成玩家:
using Mirror; using UnityEngine.SceneManagement; public class CustomNetworkManager : NetworkManager { public override void OnServerAddPlayer(NetworkConnectionToClient conn) { // 仅在Game场景才执行玩家生成逻辑 if (SceneManager.GetActiveScene().name != "Game") return; // 调用父类默认逻辑生成玩家预制体 base.OnServerAddPlayer(conn); } }
使用说明:
- 将原NetworkManager组件替换为这个自定义子类
- 确保NetworkManager的
playerPrefab已正确赋值 - 主菜单场景下,服务器收到玩家添加请求时会直接跳过;切换到Game场景后,请求才会触发玩家生成
方法2:监听场景加载事件,动态控制玩家预制体
给NetworkManager挂载辅助脚本,根据当前场景动态启用/禁用玩家生成:
using Mirror; using UnityEngine.SceneManagement; public class ScenePlayerSpawnHandler : MonoBehaviour { private NetworkManager _networkManager; void Awake() { _networkManager = GetComponent<NetworkManager>(); SceneManager.sceneLoaded += OnSceneLoaded; } void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (scene.name == "Game") { // 切换到Game场景时,赋值玩家预制体(替换为你的预制体路径) _networkManager.playerPrefab = Resources.Load<GameObject>("Prefabs/Player"); // 服务器端给已连接但未生成玩家的客户端补生成 if (_networkManager.isServer) { foreach (var conn in _networkManager.connections.Values) { if (conn.isAuthenticated && conn.identity == null) { _networkManager.OnServerAddPlayer(conn); } } } } else { // 非Game场景清空预制体,防止误生成 _networkManager.playerPrefab = null; } } void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; } }
方法3:客户端延迟请求生成玩家
让客户端在主菜单仅完成连接操作,等到Game场景加载完成后再请求生成玩家:
// 主菜单连接按钮逻辑 public void OnConnectButtonClicked() { NetworkManager.singleton.StartClient(); // 不要在这里调用NetworkClient.AddPlayer() } // Game场景初始化脚本 public class GameSceneInit : MonoBehaviour { void Start() { // 客户端已连接且未生成本地玩家时,发送生成请求 if (NetworkClient.isConnected && NetworkClient.localPlayer == null) { NetworkClient.AddPlayer(); } } }
这种方式从源头避免主菜单场景触发玩家生成请求,只有进入Game场景后才会向服务器发送生成请求,配合方法1的服务器端判断,双重保障不会在主菜单生成玩家。
内容的提问来源于stack exchange,提问作者Moni
相关产品推荐
相关产品推荐

