【问题标题】:Lobby system on Unity NetcodeUnity Netcode 上的大厅系统
【发布时间】:2021-12-08 16:19:52
【问题描述】:

我为我的游戏编写了一个大厅系统,以便玩家参加比赛。该系统作为一个实体存在。我有一个正在运行的服务器,客户端正在连接它,只要两个客户端单击“就绪”按钮,它们就会被转移到战场。理想情况下应该是这样,但什么也没有发生,没有错误,什么都没有。我写了一个日志,以便用户在控制台中单击“就绪”后显示“玩家 x 已就绪”,但在屏幕截图中给出警告

.

告诉我问题是什么。 我会附上大厅代码。

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();
        }
    }
}

【问题讨论】:

  • 请使用正确的标签!请注意,[unityscript] 是或更好曾经在早期 Unity 版本中使用的自定义 JavaScript 风格的语言,现在长期弃用。你的代码在c#

标签: c# unity3d


【解决方案1】:

我正在使我的大厅与您的大厅相似,您的大厅也可能来自 DapperDino,而 NetworkList&lt;T&gt; 对我的工作方式与教程中的方式不同。因此我所做的是我为每个玩家(在我的情况下只有两个)使用NetworkVariable&lt;LobbyPlayerState&gt; 代替(提供LobbyPlayerState 实现了INetworkSerializable 接口)并且效果很好。

【讨论】:

    猜你喜欢
    • 2022-10-02
    • 2022-01-08
    • 2010-09-30
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    • 2020-02-07
    • 2020-09-03
    • 2022-10-30
    相关资源
    最近更新 更多