[英]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.