You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 17:52:25