【问题标题】:UNet: Failed to spawn server object (NOT using NetworkManager)UNet:无法生成服务器对象(不使用 NetworkManager)
【发布时间】:2016-07-07 08:01:03
【问题描述】:

我正在使用 Unity 5 的 Networking HLAPI。 我不想使用 NetworkManager,因为我不想为 Unity 的多人游戏服务(Matchmaker 和 Relay 服务器)付费。

当客户端连接到服务器时,我试图在客户端上生成一个播放器。我可以让客户端正确连接到服务器,但是在客户端上生成失败并出现以下错误:

Failed to spawn server object, assetId=b861a662c70615a40971e7bab10e4e14 netId=1
UnityEngine.Networking.NetworkIdentity:UNetStaticUpdate()

请注意,在服务器上,玩家对象正确生成。

最少的复制:

我在一个 Unity 2D 项目中,我已将以下脚本附加到我的主相机:

using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.NetworkSystem;

public class MenuMinimalRepro : MonoBehaviour
{
    private NetworkClient networkClient;

    void OnGUI()
    {
        if (this.networkClient != null && this.networkClient.isConnected)
        {
            GUI.Label(new Rect(100, 25, 150, 25), "Running as Client");
        }
        else if (NetworkServer.active)
        {
            GUI.Label(new Rect(100, 25, 150, 25), "Running as Server");
        }
        else
        {
            if (GUI.Button(new Rect(100, 25, 150, 25), "Start as Client"))
            {
                this.StartClient();
            }
            if (GUI.Button(new Rect(100, 50, 150, 25), "Start as Server"))
            {
                this.StartServer();
            }
        }
    }

    public void StartServer()
    {
        NetworkServer.Listen(54321);
        NetworkServer.RegisterHandler(MsgType.AddPlayer, OnAddPlayerServer);
    }

    public void StartClient()
    {
        this.networkClient = new NetworkClient();
        this.networkClient.RegisterHandler(MsgType.Connect, OnConnectedClient);
        this.networkClient.Connect("localhost", 54321);
    }

    // Connected handler for the client side
    public void OnConnectedClient(NetworkMessage netMsg)
    {
        ClientScene.AddPlayer(this.networkClient.connection, 0);
    }

    // AddPlayer handler for the server side
    public void OnAddPlayerServer(NetworkMessage netMsg)
    {
        AddPlayerMessage msg = netMsg.ReadMessage<AddPlayerMessage>();
        GameObject newPlayer = (GameObject)Instantiate(Resources.Load("Prefabs/Player"));
        NetworkServer.AddPlayerForConnection(netMsg.conn, newPlayer, msg.playerControllerId);
    }
}

我的 Player 对象是一个简单的 sprite,我用 NetworkIdentity 组件 (see my Prefab in the Inspector) 将它制作成一个预制件。我的 Player Prefab 位于 Resources 文件夹中,因此我可以从代码 (see my Prefab in the Project View) 轻松加载它。

我启动游戏的后台实例(使用 Ctrl+B)并将其作为服务器启动,然后单击 Unity 编辑器中的播放按钮并将该实例作为客户端启动。然后 Unity 会报告我之前提到的错误。

有人知道我做错了什么吗?

【问题讨论】:

    标签: unity3d multiplayer unity-networking


    【解决方案1】:

    我想通了。发生的情况是,服务器通过给它一个哈希值(如错误消息中所示)来告诉客户端要实例化哪个 Prefab。问题是,在您将 Prefab 注册到 UNet 系统之前,该哈希对客户端没有任何意义。

    所以,我需要做的就是在我的问题示例中调用ClientScene.AddPlayer(...) 之前调用ClientScene.RegisterPrefab(Resources.Load("Prefabs/Player"))

    希望这对某人有所帮助!

    【讨论】:

    • 如果有人使用 NetworkingManager 处理 spwaning 并在某些时候得到以下错误:-“找不到 1 UnityEngine.Networking.NetworkIdentity:UNetStaticUpdate() 的生成场景对象”尝试重建您的预制件或删除元文件。
    【解决方案2】:

    您还想实现 OnClientConnect() 事件以在客户端上生成玩家:

    public virtual void OnClientConnect(NetworkConnection conn)
    {
        ClientScene.Ready(conn);
        ClientScene.AddPlayer(0);
    }
    

    参考:Using the Network Manager(参见在客户端调用的函数

    【讨论】:

    • 感谢您的回复,但我已经在 OnConnectedClient() 方法中这样做了。我使用不同的重载来自动执行Ready()。为了以防万一,我尝试将其更改为 2 个单独的调用,但仍然出现相同的错误。
    • 很高兴你明白了,这是我建议的下一件事。 :-)
    猜你喜欢
    • 2018-02-24
    • 1970-01-01
    • 2018-12-19
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    相关资源
    最近更新 更多