NullReferenceException when trying to join the game

Hello everybody,
So the hosting works fine, but the joining doesnt work. when i host from the editor (to see the join code), and try to join from the build nothing happens, so i added a join code display in the game scene, so i can host from the build to see the exception. and i get this every time i click the client button (even if the join code is correct/wrong):


here is my related code:

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class MainMenu : MonoBehaviour
{
    [SerializeField] private TMP_InputField joinCodeField;

    public async void StartHost()
    {
        await HostSingleton.Instance.GameManager.StartHostAsync();
    }

    public async void StartClient()
    {
        await ClientSingleton.Instance.GameManager.StartClientAsync(joinCodeField.text);
    }
}

using System.Collections;

using System.Collections.Generic;

using System.Threading.Tasks;

using UnityEngine;

public class ClientSingleton : MonoBehaviour

{

    private static ClientSingleton instance;

    public ClientGameManager GameManager {get; private set; }

    public static ClientSingleton Instance

    {

        get

        {

            if (instance != null) return instance;

            instance = FindObjectOfType<ClientSingleton>();

            if (instance = null)

            {

                Debug.LogError("No ClientSingelton found!!!!!!!!!!!");

                return null;

            }

            return instance;

        }

    }

    private void Start()

    {

        DontDestroyOnLoad(gameObject);

    }

    public async Task<bool> CreateClient()

    {

       GameManager = new ClientGameManager();

       return await GameManager.InitAsync();

    }

}

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Unity.Netcode;
using Unity.Netcode.Transports.UTP;
using Unity.Networking.Transport.Relay;
using Unity.Services.Core;
using Unity.Services.Relay;
using Unity.Services.Relay.Models;
using UnityEngine;
using UnityEngine.SceneManagement;

public class ClientGameManager
{
    private JoinAllocation allocation;

    private const string MenuSceneName = "Menu";

    public async Task<bool> InitAsync()
    {
        await UnityServices.InitializeAsync();

        AuthState authState = await AuthenticationWrapper.DoAuth();

        if(authState == AuthState.Authenticated)
        {
            return true;
        }

        return false;
    }

    public void GoToMenu()
    {
        SceneManager.LoadScene(MenuSceneName);
    }

    public async Task StartClientAsync(string joinCode)
    {
        try
        {
            allocation = await Relay.Instance.JoinAllocationAsync(joinCode);
        }
        catch(Exception e)
        {
            Debug.Log(e);
            return;
        }

        UnityTransport transport = NetworkManager.Singleton.GetComponent<UnityTransport>();

        RelayServerData relayServerData = new RelayServerData(allocation, "dtls");
        transport.SetRelayServerData(relayServerData);

        NetworkManager.Singleton.StartClient();
    }
}


i tried changing dtls to udp and its not working. i copy pasted the code from the repository and its not working. What it could be?
All the references are set correctly(host, client buttons, input fields etc.)

Update:
after some debugging it turns out that the ClientSingleton.Instance is null.

1 Like

Update: I solved the issue!
because the ClientSingleton.Instance is null i modified the main menu script:

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class MainMenu : MonoBehaviour
{
    [SerializeField] private TMP_InputField joinCodeField;

    public async void StartHost()
    {
        await HostSingleton.Instance.GameManager.StartHostAsync();
    }

    public async void StartClient()
    {
        if (ClientSingleton.Instance == null) ClientSingleton.SetInstance(FindObjectOfType<ClientSingleton>());
        await ClientSingleton.Instance.GameManager.StartClientAsync(joinCodeField.text);
    }
}

(SetInstance() is a function that i added in the ClientSingleton)

    public static void SetInstance(ClientSingleton clientSingleton)
    {
        instance = clientSingleton;
    }

this worked for me once, then stopped working. But changing “dtls” to “udp” fixed the issue :slight_smile:

1 Like

Glad you figured this out, well done!

1 Like

You are manually doing exactly what the Instance property getter is supposed to do, but there’s an error in that code. You should instead fix the error. Here’s where a typo caused you headaches (it’s in ClientSingleton):

    public static ClientSingleton Instance
    {
        get
        {
            if (instance != null) return instance;
            instance = FindObjectOfType<ClientSingleton>();
            if (instance = null) // <-- Right here
            {
                Debug.LogError("No ClientSingelton found!!!!!!!!!!!");
                return null;
            }
            return instance;
        }
    }

I have marked the offending line above. You are setting instance back to null there. = is assignment, == is comparison. You just needed to add another = and everything would have been fine. It is for this exact reason why old-school C/C++ devs write if (null == instance) (putting null first) because then it wouldn’t even compile if you try to assign something to null. Your IDE (if it’s proper) should also have complained a little about it

1 Like

Thanks, that was the issue! By the way, my IDE is visual studio code.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms