NetworkManager.Singleton.IsConnectedClient never set true when testing multiple devices

Hello,

I am working in Unity 2021.3.19f1, NGO 1.2.0, Lobby 1.1.2 and Relay 1.0.5. I currently have a simple setup where players can choose to Host a new lobby or Join (only via code). Players authenticate anonymously with a random named profile beforehand. When using the same PC I can connect multiple clients to the same lobby from both the editor and from a build. When attempting to connect two PCs to the same lobby the same code does not work and I cannot figure out why.

Here is my simple Authentication class:

    public class UnityAutheniticationService : BaseAuthenticationService
    {
        public override bool IsAuthenticated
            => _isAuthenticated;

        private bool _isAuthenticated;

#if UNITY_EDITOR
        private void OnDisable()
        {
            _isAuthenticated = false;
        }
#endif

        public override async UniTask<bool> TryAuthenticateAsync()
        {
            try
            {
                var initializationOptions = new InitializationOptions();
                initializationOptions.SetProfile($"RandomProfile-{UnityEngine.Random.Range(0, 100000)}");
                await UnityServices.InitializeAsync(initializationOptions);
                AuthenticationService.Instance.SignedIn += OnSignedIn;
                await AuthenticationService.Instance.SignInAnonymouslyAsync();
            }
            catch (Exception e)
            {
                Debug.LogError($"Failed to authenticate: {e}");
                _isAuthenticated = false;
                return false;
            }
            _isAuthenticated = true;
            return true;
        }

        private void OnSignedIn()
        {
            AuthenticationService.Instance.SignedIn -= OnSignedIn;
            Debug.LogError($"Signed in as: {AuthenticationService.Instance.PlayerId}");
        }

        public override void SignOut()
        {
            if (!AuthenticationService.Instance.IsSignedIn)
                return;
            AuthenticationService.Instance.SignOut();
            _isAuthenticated = false;
        }
    }

Here is my simple host/join class:

public class UnityMatchService : BaseMatchService
{
    private const int MaximumPlayerCount = 4;

    public override bool IsConnected => _isConnected;
    public override bool IsHost => NetworkManager.Singleton.IsHost;
    public override bool IsClient => NetworkManager.Singleton.IsClient;
    public override bool IsServer => NetworkManager.Singleton.IsServer;
    public override ulong ClientId => NetworkManager.Singleton.LocalClientId;
    public override IReadOnlyCollection<ulong> ClientIds => NetworkManager.Singleton.ConnectedClientsIds;

    public override IMatchLobby Lobby => _lobby;

    [SerializeField]
    private GameObject _networkManagerPrefab;

    [SerializeField]
    private GameObject _onlineLobbyMenuNetworkBehaviourPrefab;

    private UnityTransport _transport;
    private UnityMatchLobby _lobby;

    private bool _isConnected;
    private NetworkObject _networkedLobbyObject;
    private bool _awaitingSceneLoad;

    public override async UniTask<bool> TryHostMatchAsync()
    {
        if (_transport == null)
            CreateNetworkManagerObject(false);
        try
        {
            var lobby = await LobbyService.Instance.CreateLobbyAsync(
                $"Lobby-{UnityEngine.Random.Range(0, 100000)}",
                MaximumPlayerCount,
                new CreateLobbyOptions
                {
                    IsPrivate = true
                }
            );
            _lobby = new UnityMatchLobby(lobby, NetworkManager.Singleton.LocalClientId);
            NetworkManager.Singleton.ConnectionApprovalCallback = ApprovalCheck;
            var success = NetworkManager.Singleton.StartHost();
            if (!success)
                return success;

            _networkedLobbyObject = Instantiate(_onlineLobbyMenuNetworkBehaviourPrefab).GetComponent<NetworkObject>();
            _networkedLobbyObject.Spawn(true);
            _isConnected = true;
            SubscribeToNetworkSceneManager();
            return _isConnected;
        }
        catch(Exception e)
        {
            Debug.LogError($"Failed to host match: {e}");
            _isConnected = false;
            return false;
        }
    }

    public override async UniTask<bool> TryJoinMatch(string code)
    {
        if (_transport == null)
            CreateNetworkManagerObject(false);
        try
        {
            var lobby = await LobbyService.Instance.JoinLobbyByCodeAsync(
                code,
                new JoinLobbyByCodeOptions
                {
                    Player = new Player(AuthenticationService.Instance.PlayerId)
                }
            );
            Debug.Log($"Lobby: {lobby.Id}");
            _lobby = new UnityMatchLobby(lobby, NetworkManager.Singleton.LocalClientId);
            var success = NetworkManager.Singleton.StartClient();
            Debug.Log($"Start client: {success}");
            if (!success)
                return success;
            while (!NetworkManager.Singleton.IsConnectedClient)
            {
                await UniTask.NextFrame();
                Debug.Log($"Waiting for IsConnectedClient...");
            }
            _isConnected = true;
            Debug.Log($"Connected successfully!");
            SubscribeToNetworkSceneManager();
            return _isConnected;
        }
        catch(Exception e)
        {
            Debug.LogError($"Failed to join lobby: {e}");
            _isConnected = false;
            return false;
        }
    }

 private void CreateNetworkManagerObject(bool simulateLatency)
 {
     _transport = Instantiate(_networkManagerPrefab).GetComponent<UnityTransport>();
     if (simulateLatency)
         _transport.SetDebugSimulatorParameters(
             packetDelay: 50,
             packetJitter: 2,
             dropRate: 0
         );
     DontDestroyOnLoad(_transport.gameObject);
     SubscribeToNetworkManager();
 }

private void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
{
    response.Approved = true;
    response.CreatePlayerObject = true;
}
}

It is worth noting that when testing across multiple devices it appears that the join code gets stuck in the while (!NetworkManager.Singleton.IsConnectedClient) loop, indicating that this value is never set to true. I do not get any warning or errors when this occurs. Any ideas?

I’m having the same issue… Any updates on this?