Search Unity

Bug Players who entered the lobby are unable to join the game as lobby details are not updated

Discussion in 'Multiplayer' started by thelaughingzasshu, Jan 21, 2024.

  1. thelaughingzasshu

    thelaughingzasshu

    Joined:
    Jan 1, 2024
    Posts:
    12
    Hello, I am currently experiencing an issue where if a player joins a lobby and waits until the lobby is full, the player will not enter the game/enter the game scene as intended. From debugging, I realised that even when new players joined the lobby after player A creates/joins the lobby, the number of players counted in the lobby in player A's side remains the same, even after implementing lobby callbacks like LobbyChanged. By right, all players should automatically enter the next scene after the lobby they have joined is full. Below is the code. Would greatly appreciate the help!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Services.Core;
    5. using Unity.Services.Authentication;
    6. using Unity.Services.Lobbies;
    7. using Unity.Services.Lobbies.Models;
    8. using Unity.Netcode;
    9. using UnityEngine.SceneManagement;
    10. using UnityEngine.UIElements;
    11.  
    12. public class PlayerLobby : MonoBehaviour
    13. {
    14.     private Lobby joinedLobby;
    15.     private float heartbeat;
    16.     public static PlayerLobby Instance { get; private set; }
    17.     public static NetworkManager Singleton { get; private set; }
    18.     private bool loading = false;
    19.     LobbyEventCallbacks m_LobbyEventCallbacks;
    20.  
    21.     private void Awake()
    22.     {
    23.         if (Instance != null && Instance != this) Destroy(gameObject);
    24.         else
    25.         {
    26.             Instance = this;
    27.             DontDestroyOnLoad(gameObject);
    28.         }
    29.     }
    30.  
    31.     // Start is called before the first frame update
    32.     async void Start()
    33.     {      
    34.         if (UnityServices.State != ServicesInitializationState.Initialized)
    35.         {
    36.             InitializationOptions options = new InitializationOptions();
    37.             options.SetProfile(Random.Range(0,9999999).ToString());
    38.  
    39.             await UnityServices.InitializeAsync(options);
    40.             AuthenticationService.Instance.SignedIn += () =>
    41.             {
    42.                 Debug.Log(AuthenticationService.Instance.PlayerId);
    43.             };
    44.             await AuthenticationService.Instance.SignInAnonymouslyAsync();
    45.         }
    46.  
    47.         m_LobbyEventCallbacks = new LobbyEventCallbacks();
    48.         m_LobbyEventCallbacks.LobbyChanged += OnLobbyChanged;
    49.     }
    50.  
    51.     // Update is called once per frame
    52.     void Update()
    53.     {
    54.         HandleHeartbeat();
    55.  
    56.         if (loading)
    57.         {
    58.             //joinedLobby = await LobbyService.Instance.GetLobbyAsync(joinedLobby.Id);
    59.             Debug.Log(joinedLobby.Players.Count);
    60.             if (joinedLobby != null && joinedLobby.Players.Count == joinedLobby.MaxPlayers)
    61.             {
    62.                 SceneManager.LoadScene("Arena", LoadSceneMode.Single);
    63.                 if (Ishost(joinedLobby))
    64.                 {
    65.                     NetworkManager.Singleton.StartHost();
    66.                 }
    67.                 else
    68.                 {
    69.                     NetworkManager.Singleton.StartClient();
    70.                 }
    71.  
    72.                 NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnect;
    73.                 loading = false;
    74.             }
    75.         }
    76.     }
    77.  
    78.     public async void HandleHeartbeat()
    79.     {
    80.         if (joinedLobby != null && Ishost(joinedLobby))
    81.         {
    82.             heartbeat -= Time.deltaTime;
    83.  
    84.             if (heartbeat < 0f)
    85.             {
    86.                 float heartbeatmax = 15f;
    87.                 heartbeat = heartbeatmax;
    88.  
    89.                 await LobbyService.Instance.SendHeartbeatPingAsync(joinedLobby.Id);
    90.             }
    91.         }
    92.     }
    93.  
    94.     private void OnLobbyChanged(ILobbyChanges lobbyChanges)
    95.     {
    96.         if (joinedLobby != null && !lobbyChanges.LobbyDeleted)
    97.         {
    98.             lobbyChanges.ApplyToLobby(joinedLobby);
    99.  
    100.             // Add logging to see changes
    101.             Debug.Log("Lobby Changed:");
    102.             Debug.Log($"Players Count: {joinedLobby.Players.Count}");
    103.             Debug.Log($"Max Players: {joinedLobby.MaxPlayers}");
    104.         }
    105.     }
    106.  
    107.     public async void CreateLobby(bool privated)
    108.     {      
    109.         CreateLobbyOptions options = new CreateLobbyOptions
    110.         {
    111.             IsPrivate = privated,
    112.         };
    113.  
    114.         Lobby lobby = await LobbyService.Instance.CreateLobbyAsync("Goat", 2, options);
    115.         await Lobbies.Instance.JoinLobbyByIdAsync(lobby.Id);
    116.         joinedLobby = lobby;
    117.         loading = true;
    118.         if (privated) {
    119.             FindObjectOfType<Menu>().PrivateQueue(true);
    120.             FindObjectOfType<Menu>().ShowCode($"Waiting for a friend...\n\nLobby code: {joinedLobby.LobbyCode}");
    121.         }  
    122.     }
    123.  
    124.     public async void JoinLobby(string mode, string code)
    125.     {
    126.         if (string.IsNullOrEmpty(code)) return;
    127.  
    128.         try
    129.         {
    130.             if (mode == "id") joinedLobby = await Lobbies.Instance.JoinLobbyByIdAsync(code);
    131.             else if (mode == "code") joinedLobby = await Lobbies.Instance.JoinLobbyByCodeAsync(code);
    132.             loading = true;          
    133.         } catch (LobbyServiceException ex) {
    134.             FindObjectOfType<Menu>().LobbyExist(true);
    135.             Debug.Log(ex);
    136.         }      
    137.     }
    138.  
    139.     public async void QuickJoinLobby()
    140.     {
    141.         try
    142.         {
    143.             QueryResponse query = await Lobbies.Instance.QueryLobbiesAsync(new QueryLobbiesOptions
    144.             {
    145.                 Filters = new List<QueryFilter>
    146.                     {
    147.                         new QueryFilter(
    148.                             field: QueryFilter.FieldOptions.AvailableSlots,
    149.                             op: QueryFilter.OpOptions.GT,
    150.                             value: "0")
    151.                     },
    152.                 Order = new List<QueryOrder>
    153.                     {
    154.                         new QueryOrder(true, QueryOrder.FieldOptions.Created),
    155.                     }
    156.             });
    157.  
    158.             if (query.Results.Count == 0)
    159.             {
    160.                 CreateLobby(false);
    161.                 Debug.Log("Lobby created");
    162.             }
    163.             else
    164.             {
    165.                 JoinLobby("id", query.Results[0].Id);
    166.                 Debug.Log("Lobby joined");
    167.             }
    168.  
    169.         }
    170.         catch (LobbyServiceException ex)
    171.         {
    172.             Debug.Log(ex);
    173.         }
    174.     }
    175.  
    176.     private bool Ishost(Lobby lobby)
    177.     {
    178.         return lobby.HostId == AuthenticationService.Instance.PlayerId;
    179.     }
    180.  
    181.     private void OnClientDisconnect(ulong id)
    182.     {
    183.         LeaveLobby(true);
    184.     }
    185.  
    186.     public async void LeaveLobby(bool left)
    187.     {
    188.         try
    189.         {
    190.             await LobbyService.Instance.DeleteLobbyAsync(joinedLobby.Id);
    191.             joinedLobby = null;
    192.             if (left)
    193.             {
    194.                 NetworkManager.Singleton.Shutdown(true);
    195.                 Destroy(NetworkManager.Singleton.gameObject);
    196.                 SceneManager.LoadScene("Menu", LoadSceneMode.Single);
    197.             }              
    198.             loading = false;
    199.         }
    200.         catch (LobbyServiceException ex)
    201.         {
    202.             Debug.Log(ex);
    203.         }
    204.     }
    205.  
    206.     public async void ListLobbies()
    207.     {
    208.         QueryResponse query = await Lobbies.Instance.QueryLobbiesAsync();
    209.     }
    210. }
    211.