0

我正在尝试根据播放器平台生成不同的预制件。因此,我将覆盖 NetworkLobbyManager 以按照我想要的方式生成对象。因此,我创建了一个将 connectionId 与预制件的索引相关联的字典,然后根据该索引实例化一个预制件。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class LobbyManager : NetworkLobbyManager
{
    private Dictionary<int, int> m_currentPlayers;

    void Start()
    {
        m_currentPlayers = new Dictionary<int, int>();
    }

    void AddPlayer(NetworkConnection conn)
    {
        if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer)
        {
            m_currentPlayers.Add(conn.connectionId, 0);
        }
        else if (Application.platform == RuntimePlatform.Android)
        {
            m_currentPlayers.Add(conn.connectionId, 1);
        }
    }

    public override GameObject OnLobbyServerCreateLobbyPlayer(NetworkConnection conn, short playerControllerId)
    {
        AddPlayer(conn);

        return base.OnLobbyServerCreateLobbyPlayer(conn, playerControllerId);
    }

    public override GameObject OnLobbyServerCreateGamePlayer(NetworkConnection conn, short playerControllerId)
    {
        GameObject go = Instantiate(spawnPrefabs[m_currentPlayers[conn.connectionId]]);
        NetworkServer.AddPlayerForConnection(conn, go, playerControllerId);

        return go;
    }
}

但是使用此代码,客户端上的生成播放器始终与主机相同,我不知道为什么,因为我似乎覆盖了正确的功能,我在这里看到了http://abrgame.blogspot.fr/2016 /01/using-unet-to-spawn-different-player.html一个使用相同技术并且对他有用的人......

4

1 回答 1

0

你的问题

if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer)
{
    m_currentPlayers.Add(conn.connectionId, 0);
}
else if (Application.platform == RuntimePlatform.Android)
{
    m_currentPlayers.Add(conn.connectionId, 1);
}

当作为客户端或主机启动时,该NetworkLobbyManager组件的行为不同,但最终,如果我是正确的,主机会处理玩家生成。在您的代码中,这意味着组件仅查看其自己的平台,而不查看连接玩家的平台

可能的解决方案

您需要将连接播放器的平台信息传递给主机。您可以创建一个NetworkConnection获取并携带平台信息的派生类,NetworkClient其派生类使用您的自定义NetworkConnection类,最终调整您自己的NetworkLobbyManager派生类以提取平台信息并使用它。

//NetworkClient

public class MyNetworkClient: NetworkClient
{
    public MyNetworkClient() : base()
    {
        SetNetworkConnectionClass<MyNetworkConnection>();
    }
}

//NetworkConnection class

public class MyNetworkConnection : NetworkConnection
{
    private RuntimePlatform connectionPlatform;

    public MyNetworkConnection() : base()
    {
        connectionPlatform = Application.platform;
    }

    public RuntimePlatform ConnectionPlatform { get { return connectionPlatform; } }
}

// Suggested adjustment for your NetworkLobbyManagerClass

void AddPlayer(MyNetworkConnection conn)
{
    // I like switches, it's a question of taste imo
    switch(conn.ConnectionPlatform)
    {
        case RuntimePlatform.Android:
            m_currentPlayers.Add(conn.connectionId, 1);
            break;
        case RuntimePlatform.WindowsEditor:
        case RuntimePlatform.WindowsPlayer:
        default:
            m_currentPlayers.Add(conn.connectionId, 0);
    }
}

public override GameObject OnLobbyServerCreateLobbyPlayer(NetworkConnection conn, short playerControllerId)
{
    // Explicitely pass your custom class
    AddPlayer(conn as MyNetworkConnection);
    return base.OnLobbyServerCreateLobbyPlayer(conn, playerControllerId);
}

public override GameObject OnLobbyServerCreateGamePlayer(NetworkConnection conn, short playerControllerId)
{
    GameObject go = Instantiate(spawnPrefabs[m_currentPlayers[conn.connectionId]]);
    NetworkServer.AddPlayerForConnection(conn, go, playerControllerId);

    return go;
}

我想听听你是否有效。:)

编辑:由于MyNetworkConnection继承自NetworkConnection,它应该能够作为NetworkConnection参数传递。这意味着,您可以保留被覆盖的方法,但是您需要明确地将您的MyNetworkConnection类传递给您的AddPlayer方法。

于 2018-05-11T08:42:17.140 回答