C# 防止Unity网络大厅中的空游戏室被破坏

C# 防止Unity网络大厅中的空游戏室被破坏,c#,visual-studio,unity3d,multiplayer,C#,Visual Studio,Unity3d,Multiplayer,软件:Unity 2018.1 语言:C#4 插件:网络大厅 问题: 我有我的统一网络大厅设置和工作。我试图防止所有玩家离开游戏室或断开连接时游戏室被破坏,以便以后可以随时返回游戏室 尝试: 我尝试将int I=0更改为I=-1(不起作用,没有影响) 我尝试将if(p!=null)更改为if(p==null)(不起作用,没有影响) 我试着用“Command,/”使代码静音。(不起作用,没有影响) 代码如下: public override void OnLobbyServerPlayerRem

软件:Unity 2018.1 语言:C#4 插件:网络大厅

问题:

我有我的统一网络大厅设置和工作。我试图防止所有玩家离开游戏室或断开连接时游戏室被破坏,以便以后可以随时返回游戏室

尝试: 我尝试将
int I=0
更改为
I=-1
(不起作用,没有影响) 我尝试将
if(p!=null)
更改为
if(p==null)
(不起作用,没有影响) 我试着用“Command,/”使代码静音。(不起作用,没有影响)

代码如下:

 public override void OnLobbyServerPlayerRemoved(NetworkConnection conn, short playerControllerId)
    {
        for (int i = 0; i < lobbySlots.Length; ++i)
        {
            LobbyPlayer p = lobbySlots[i] as LobbyPlayer;

            if (p != null)
            {
                p.RpcUpdateRemoveButton();
                p.ToggleJoinButton(numPlayers + 1 >= minPlayers);
            }
        }
    }

    public override void OnLobbyServerDisconnect(NetworkConnection conn)
    {
        for (int i = 0; i < lobbySlots.Length; ++i)
        {
            LobbyPlayer p = lobbySlots[i] as LobbyPlayer;

            if (p != null)
            {
                p.RpcUpdateRemoveButton();
                p.ToggleJoinButton(numPlayers >= minPlayers);
            }
        }

    }
public override void OnLobbyServerPlayerRemoved(网络连接连接,短播放控制器ID)
{
对于(int i=0;i=minPlayers);
}
}
}
公共覆盖无效OnLobbyServerDisconnect(网络连接连接)
{
对于(int i=0;i=minPlayers);
}
}
}
完整代码:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine.Networking;
using UnityEngine.Networking.Types;
using UnityEngine.Networking.Match;
using System.Collections;


namespace Prototype.NetworkLobby
{
public class LobbyManager : NetworkLobbyManager 
{
    static short MsgKicked = MsgType.Highest + 1;

    static public LobbyManager s_Singleton;


    [Header("Unity UI Lobby")]
    [Tooltip("Time in second between all players ready & match start")]
    public float prematchCountdown = 5.0f;

    [Space]
    [Header("UI Reference")]
    public LobbyTopPanel topPanel;

    public RectTransform mainMenuPanel;
    public RectTransform lobbyPanel;

    public LobbyInfoPanel infoPanel;
    public LobbyCountdownPanel countdownPanel;
    public GameObject addPlayerButton;

    protected RectTransform currentPanel;

    public Button backButton;

    public Text statusInfo;
    public Text hostInfo;

    //Client numPlayers from NetworkManager is always 0, so we count 
(throught connect/destroy in LobbyPlayer) the number
    //of players, so that even client know how many player there is.
    [HideInInspector]
    public int _playerNumber = 0;

    //used to disconnect a client properly when exiting the matchmaker
    [HideInInspector]
    public bool _isMatchmaking = false;

    protected bool _disconnectServer = false;

    protected ulong _currentMatchID;

    protected LobbyHook _lobbyHooks;

    void Start()
    {
        s_Singleton = this;
        _lobbyHooks = GetComponent<Prototype.NetworkLobby.LobbyHook>();
        currentPanel = mainMenuPanel;

        backButton.gameObject.SetActive(false);
        GetComponent<Canvas>().enabled = true;

        DontDestroyOnLoad(gameObject);

        SetServerInfo("Offline", "None");
    }

    public override void OnLobbyClientSceneChanged(NetworkConnection conn)
    {
        if (SceneManager.GetSceneAt(0).name == lobbyScene)
        {
            if (topPanel.isInGame)
            {
                ChangeTo(lobbyPanel);
                if (_isMatchmaking)
                {
                    if (conn.playerControllers[0].unetView.isServer)
                    {
                        backDelegate = StopHostClbk;
                    }
                    else
                    {
                        backDelegate = StopClientClbk;
                    }
                }
                else
                {
                    if (conn.playerControllers[0].unetView.isClient)
                    {
                        backDelegate = StopHostClbk;
                    }
                    else
                    {
                        backDelegate = StopClientClbk;
                    }
                }
            }
            else
            {
                ChangeTo(mainMenuPanel);
            }

            topPanel.ToggleVisibility(true);
            topPanel.isInGame = false;
        }
        else
        {
            ChangeTo(null);

            Destroy(GameObject.Find("MainMenuUI(Clone)"));

            //backDelegate = StopGameClbk;
            topPanel.isInGame = true;
            topPanel.ToggleVisibility(false);
        }
    }

    public void ChangeTo(RectTransform newPanel)
    {
        if (currentPanel != null)
        {
            currentPanel.gameObject.SetActive(false);
        }

        if (newPanel != null)
        {
            newPanel.gameObject.SetActive(true);
        }

        currentPanel = newPanel;

        if (currentPanel != mainMenuPanel)
        {
            backButton.gameObject.SetActive(true);
        }
        else
        {
            backButton.gameObject.SetActive(false);
            SetServerInfo("Offline", "None");
            _isMatchmaking = false;
        }
    }

    public void DisplayIsConnecting()
    {
        var _this = this;
        infoPanel.Display("Connecting...", "Cancel", () => { _this.backDelegate(); });
    }

    public void SetServerInfo(string status, string host)
    {
        statusInfo.text = status;
        hostInfo.text = host;
    }


    public delegate void BackButtonDelegate();
    public BackButtonDelegate backDelegate;
    public void GoBackButton()
    {
        backDelegate();
        topPanel.isInGame = false;
    }

    // ----------------- Server management

    public void AddLocalPlayer()
    {
        TryToAddPlayer();
    }

    public void RemovePlayer(LobbyPlayer player)
    {
        player.RemovePlayer();
    }

    public void SimpleBackClbk()
    {
        ChangeTo(mainMenuPanel);
    }

    public void StopHostClbk()
    {
        if (_isMatchmaking)
        {
            matchMaker.DestroyMatch((NetworkID)_currentMatchID, 0, OnDestroyMatch);
            _disconnectServer = true;
        }
        else
        {
            StopHost();
        }


        ChangeTo(mainMenuPanel);
    }

    public void StopClientClbk()
    {
        StopClient();

        if (_isMatchmaking)
        {
            StopMatchMaker();
        }

        ChangeTo(mainMenuPanel);
    }

    public void StopServerClbk()
    {
        StopServer();
        ChangeTo(mainMenuPanel);
    }

    class KickMsg : MessageBase { }
    public void KickPlayer(NetworkConnection conn)
    {
        conn.Send(MsgKicked, new KickMsg());
    }




    public void KickedMessageHandler(NetworkMessage netMsg)
    {
        infoPanel.Display("Kicked by Server", "Close", null);
        netMsg.conn.Disconnect();
    }

    //===================

    public override void OnStartHost()
    {
        base.OnStartHost();

        ChangeTo(lobbyPanel);
        backDelegate = StopHostClbk;
        SetServerInfo("Hosting", networkAddress);
    }

    public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
    {
        base.OnMatchCreate(success, extendedInfo, matchInfo);
        _currentMatchID = (System.UInt64)matchInfo.networkId;
    }

    public override void OnDestroyMatch(bool success, string extendedInfo)
    {
        base.OnDestroyMatch(success, extendedInfo);
        if (_disconnectServer)
        {
            StopMatchMaker();
            StopHost();
        }
    }

    //allow to handle the (+) button to add/remove player
    public void OnPlayersNumberModified(int count)
    {
        _playerNumber += count;

        int localPlayerCount = 0;
        foreach (PlayerController p in ClientScene.localPlayers)
            localPlayerCount += (p == null || p.playerControllerId == -1) ? 0 : 1;

        addPlayerButton.SetActive(localPlayerCount < maxPlayersPerConnection && _playerNumber < maxPlayers);
    }

    // ----------------- Server callbacks ------------------

    //we want to disable the button JOIN if we don't have enough player
    //But OnLobbyClientConnect isn't called on hosting player. So we override the lobbyPlayer creation
    public override GameObject OnLobbyServerCreateLobbyPlayer(NetworkConnection conn, short playerControllerId)
    {
        GameObject obj = Instantiate(lobbyPlayerPrefab.gameObject) as GameObject;

        LobbyPlayer newPlayer = obj.GetComponent<LobbyPlayer>();
        newPlayer.ToggleJoinButton(numPlayers + 1 >= minPlayers);


        for (int i = 0; i < lobbySlots.Length; ++i)
        {
            LobbyPlayer p = lobbySlots[i] as LobbyPlayer;

            if (p != null)
            {
                p.RpcUpdateRemoveButton();
                p.ToggleJoinButton(numPlayers + 1 >= minPlayers);
            }
        }

        return obj;
    }

    public override void OnLobbyServerPlayerRemoved(NetworkConnection conn, short playerControllerId)
    {
        for (int i = 0; i < lobbySlots.Length; ++i)
        {
            LobbyPlayer p = lobbySlots[i] as LobbyPlayer;

            if (p != null)
            {
                p.RpcUpdateRemoveButton();
                p.ToggleJoinButton(numPlayers + 1 >= minPlayers);
            }
        }
    }

    public override void OnLobbyServerDisconnect(NetworkConnection conn)
    {
        for (int i = 0; i < lobbySlots.Length; ++i)
        {
            LobbyPlayer p = lobbySlots[i] as LobbyPlayer;

            if (p != null)
            {
                p.RpcUpdateRemoveButton();
                p.ToggleJoinButton(numPlayers >= minPlayers);
            }
        }

    }

    public override bool OnLobbyServerSceneLoadedForPlayer(GameObject lobbyPlayer, GameObject gamePlayer)
    {
        //This hook allows you to apply state data from the lobby-player to the game-player
        //just subclass "LobbyHook" and add it to the lobby object.

        if (_lobbyHooks)
            _lobbyHooks.OnLobbyServerSceneLoadedForPlayer(this, lobbyPlayer, gamePlayer);

        return true;
    }

    // --- Countdown management

    public override void OnLobbyServerPlayersReady()
    {
        bool allready = true;
        for(int i = 0; i < lobbySlots.Length; ++i)
        {
            if(lobbySlots[i] != null)
                allready &= lobbySlots[i].readyToBegin;
        }

        if(allready)
            StartCoroutine(ServerCountdownCoroutine());
    }

    public IEnumerator ServerCountdownCoroutine()
    {
        float remainingTime = prematchCountdown;
        int floorTime = Mathf.FloorToInt(remainingTime);

        while (remainingTime > 0)
        {
            yield return null;

            remainingTime -= Time.deltaTime;
            int newFloorTime = Mathf.FloorToInt(remainingTime);

            if (newFloorTime != floorTime)
            {//to avoid flooding the network of message, we only send a notice to client when the number of plain seconds change.
                floorTime = newFloorTime;

                for (int i = 0; i < lobbySlots.Length; ++i)
                {
                    if (lobbySlots[i] != null)
                    {//there is maxPlayer slots, so some could be == null, need to test it before accessing!
                        (lobbySlots[i] as LobbyPlayer).RpcUpdateCountdown(floorTime);
                    }
                }
            }
        }

        for (int i = 0; i < lobbySlots.Length; ++i)
        {
            if (lobbySlots[i] != null)
            {
                (lobbySlots[i] as LobbyPlayer).RpcUpdateCountdown(0);
            }
        }

        ServerChangeScene(playScene);
    }

    // ----------------- Client callbacks ------------------

    public override void OnClientConnect(NetworkConnection conn)
    {
        base.OnClientConnect(conn);

        infoPanel.gameObject.SetActive(false);

        conn.RegisterHandler(MsgKicked, KickedMessageHandler);

        if (!NetworkServer.active)
        {//only to do on pure client (not self hosting client)
            ChangeTo(lobbyPanel);
            //backDelegate = StopClientClbk;
            SetServerInfo("Client", networkAddress);
        }
    }


    public override void OnClientDisconnect(NetworkConnection conn)
    {
        base.OnClientDisconnect(conn);
        ChangeTo(mainMenuPanel);
    }

    public override void OnClientError(NetworkConnection conn, int errorCode)
    {
        ChangeTo(mainMenuPanel);
        infoPanel.Display("Cient error : " + (errorCode == 6 ? "timeout" : errorCode.ToString()), "Close", null);
    }
  }
}
使用UnityEngine;
使用UnityEngine.UI;
使用UnityEngine.SceneManagement;
使用UnityEngine。联网;
使用UnityEngine.Networking.Types;
使用UnityEngine.Networking.Match;
使用系统集合;
namespace Prototype.networklobb
{
公共类LobbyManager:NetworkLobbyManager
{
静态短MsgKicked=MsgType.Highest+1;
静态公共游说经理s_Singleton;
[标题(“Unity UI大厅”)]
[工具提示(“所有玩家准备就绪和比赛开始之间的时间(秒))]
公共浮动预计数=5.0f;
[空格]
[标题(“UI引用”)]
公共说客托帕内尔托帕内尔;
公共菜单面板;
公共游说小组;
公共游说机构infoPanel infoPanel;
公众游说小组;
公共游戏对象addPlayerButton;
保护面板;
公共按钮后退按钮;
公共文本状态信息;
公共文本主机信息;
//NetworkManager中的客户端数始终为0,因此我们计算
(通过LobbyPlayer中的连接/销毁)号码
//玩家数量,这样即使是客户也知道有多少玩家。
[hideininstecpt]
public int_playerNumber=0;
//用于在退出matchmaker时正确断开客户端连接
[hideininstecpt]
公共bool\u isMatchmaking=假;
受保护的bool\u disconnectServer=false;
受保护的ulong\u currentMatchID;
受保护的大厅挂钩(LobbyHook);;
void Start()
{
s_Singleton=这;
_lobbyHooks=GetComponent();
currentPanel=mainMenuPanel;
backButton.gameObject.SetActive(false);
GetComponent().enabled=true;
DontDestroyOnLoad(游戏对象);
SetServerInfo(“脱机”、“无”);
}
public override void OnLobbyClientSceneChanged(网络连接连接)
{
if(SceneManager.GetSceneAt(0.name==LobbySene)
{
如果(托帕内尔·伊辛格)
{
改为(游说小组);
如果(_isMatchmaking)
{
if(conn.playerControllers[0].unetView.isServer)
{
backDelegate=StopHostClbk;
}
其他的
{
backDelegate=StopClientClbk;
}
}
其他的
{
if(conn.playerController[0].unetView.isClient)
{
backDelegate=StopHostClbk;
}
其他的
{
backDelegate=StopClientClbk;
}
}
}
其他的
{
更改为(mainMenuPanel);
}
topPanel.切换可见性(真);
topPanel.isInGame=错误;
}
其他的
{
更改为(空);
销毁(GameObject.Find(“MainMenuUI(克隆)”);
//backDelegate=StopGameClbk;
topPanel.isInGame=真;
topPanel.ToggleVisibility(假);
}
}
公共无效更改为(RectTransform newPanel)
{
如果(currentPanel!=null)
{
currentPanel.gameObject.SetActive(false);
}
if(newPanel!=null)
{
newPanel.gameObject.SetActive(true);
}
currentPanel=新建面板;
如果(currentPanel!=mainMenuPanel)
{
backButton.gameObject.SetActive(true);
}
其他的
{
backButton.gameObject.SetActive(false);
SetServerInfo(“脱机”、“无”);
_isMatchmaking=假;
}
}
public void displayiconnecting()
{
var_this=这个;
infoPanel.Display(“连接…”,“取消”,()=>{u this.backDelegate();});
}
public void SetServerInfo(字符串状态,字符串主机)
{
statusInfo.text=状态;
hostInfo.text=主机;
}
公共委托void backbuttonelegate();
公共backbuttonelegate backDelegate;
公共void GoBackButton()
{
backDelegate();
topPanel.isInGame=错误;
}
//--------------服务器管理
public void AddLocalPlayer()
{
TryToAddPlayer();
}
public void RemovePlayer(游说玩家)
{
player.RemovePlayer();
}
public void SimpleBackClbk()
{
更改为(mainMenuPanel);
}
公共空间