简体   繁体   English

Unity Netcode 上的大厅系统

[英]Lobby system on Unity Netcode

I wrote a lobby system for my game so that players would go to a match.我为我的游戏编写了一个大厅系统,以便玩家可以 go 参加比赛。 This system exists as an entity.该系统作为一个实体存在。 I have a running server, clients are connecting to it, and as soon as two clients click the "Ready" button, they will be transferred to the field of battle.我有一个正在运行的服务器,客户端正在连接到它,只要两个客户端单击“就绪”按钮,它们就会被转移到战场上。 This should ideally be, but nothing happens, no errors, nothing.理想情况下应该是这样,但是没有任何反应,没有错误,什么也没有。 I wrote a log so that after the user clicks "Ready" in the console it says "Player x is ready", but gives a warning in the screenshot我写了一个日志,以便在用户单击控制台中的“就绪”后,它会显示“玩家 x 已准备就绪”,但会在屏幕截图中发出警告

. .

Tell me what the problem is.告诉我问题是什么。 I will attach the lobby code.我会附上大堂代码。

using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;

namespace vsamomdeletak.Scripts.Networking
{
    public class LobbyUI : NetworkBehaviour
    {
        private NetworkList<LobbyPlayerState> lobbyPlayers;

        private void Awake()
        {
            lobbyPlayers = new NetworkList<LobbyPlayerState>();
        }

        public override void OnNetworkSpawn()
        {

            if (IsServer)
            {
                NetworkManager.Singleton.OnClientConnectedCallback += HandleClientConnected;
                NetworkManager.Singleton.OnClientDisconnectCallback += HandleClientDisconnect;

                foreach (NetworkClient client in NetworkManager.Singleton.ConnectedClientsList)
                {
                    HandleClientConnected(client.ClientId);
                }
            }
        }

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


            if (NetworkManager.Singleton)
            {
                NetworkManager.Singleton.OnClientConnectedCallback -= HandleClientConnected;
                NetworkManager.Singleton.OnClientDisconnectCallback -= HandleClientDisconnect;
            }
        }

        private bool IsEveryoneReady()
        {
            if (lobbyPlayers.Count < 2)
            {
                return false;
            }

            foreach (var player in lobbyPlayers)
            {
                if (!player.IsReady)
                {
                    return false;
                }
            }

            return true;
        }

        private void HandleClientConnected(ulong clientId)
        {
            var playerData = ServerGameNetPortal.Instance.GetPlayerData(clientId);

            if (!playerData.HasValue) { return; }

            lobbyPlayers.Add(new LobbyPlayerState(
                clientId,
                playerData.Value.PlayerName,
                false
            ));
        }

        private void HandleClientDisconnect(ulong clientId)
        {
            for (int i = 0; i < lobbyPlayers.Count; i++)
            {
                if (lobbyPlayers[i].ClientId == clientId)
                {
                    lobbyPlayers.RemoveAt(i);
                    break;
                }
            }
        }

        [ServerRpc(RequireOwnership = false)]
        private void ToggleReadyServerRpc(ServerRpcParams serverRpcParams = default)
        {
            for (int i = 0; i < lobbyPlayers.Count; i++)
            {
                if (lobbyPlayers[i].ClientId == serverRpcParams.Receive.SenderClientId)
                {
                    lobbyPlayers[i] = new LobbyPlayerState(
                        lobbyPlayers[i].ClientId,
                        lobbyPlayers[i].PlayerName,
                        !lobbyPlayers[i].IsReady
                    );
                    Debug.Log("Player" + i + "Ready");
                }
            }

            if (IsEveryoneReady())
            {
                StartGameServerRpc();
            }
        }

        [ServerRpc(RequireOwnership = false)]
        private void StartGameServerRpc(ServerRpcParams serverRpcParams = default)
        {
            if (serverRpcParams.Receive.SenderClientId != NetworkManager.Singleton.LocalClientId) { return; }

            if (!IsEveryoneReady()) { return; }

            ServerGameNetPortal.Instance.StartGame();
        }

        public void OnLeaveClicked()
        {
            GameNetPortal.Instance.RequestDisconnect();
        }

        public void OnReadyClicked()
        {
            ToggleReadyServerRpc();
        }
    }
}

I am making my lobby similiar to yours, yours is also probably from DapperDino, and NetworkList<T> did'nt work for me the same way it did in the tutorial.我正在使我的大厅与您的大厅相似,您的大厅也可能来自 DapperDino,并且NetworkList<T>对我的工作方式与教程中的方式不同。 Therefore what I did was I used NetworkVariable<LobbyPlayerState> instead (provide LobbyPlayerState has implemented INetworkSerializable interface) for every player (in my case it was only two) and it worked fine.因此,我所做的是为每个播放器(在我的例子中只有两个)使用NetworkVariable<LobbyPlayerState>代替(提供LobbyPlayerState已实现INetworkSerializable接口)并且它工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM