Pass value to another class in another scene - NullReferenceException

I’m new to Unity, so please have in mind that I might miss some basic concept here. I’ll try to describe what is my aim and how I tried to achieve it, and if even the simplest question cross your mind, please share it, as it may be the solution.

I have 2 scenes: Menu and MainScene.

In Menu I have Menu object, which contains 2 Dropdowns and 2 Buttons. To that Menu i have attached script Menu.cs. In that script I have no problem reading value from Dropdown and saving it to a different variable then printing the value by Debug.Log().

In MainScene I have NPC object with Traveling.cs script attached to it. I’d like to pass here the values from Menu.cs script and decide what to do depending on these values. But after I click Next Button which triggers passing values and loads MainScene, I got error:

which points me to this line:

traveling.ReadDropdowns(algorithmName, checkpointsAmount);

Below are codes for both classes:

Traveling.cs:

public class Traveling : MonoBehaviour
{
    private int checkpoints;
    private string algorithm;

    public void ReadDropdowns(string algorithmName, string checkpointsAmount)
    {
        algorithm = algorithmName;
        checkpoints = Convert.ToInt32(checkpointsAmount);
    }
}

Menu.cs:

public class Menu : MonoBehaviour
{
    List<string> algorithms = new List<string>() { "Insertion", "Brute-force", "Random checkpoints" };
    List<string> checkpoints = new List<string>() { "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" };
    public Dropdown checkpointsDropdown;
    public Dropdown algorithmDropdown;
    public string algorithmName;
    public string checkpointsAmount;
    public Traveling traveling;


    void Awake()
    {
        traveling = GameObject.FindObjectOfType<Traveling>();
    }

    void Start()
    {
        algorithmDropdown.AddOptions(algorithms);
        checkpointsDropdown.AddOptions(checkpoints);
    }

    public void dropdownAlgorithm_IndexChanged(int index)
    {
        algorithmName = algorithms[index];
        Debug.Log(algorithmName);
    }

    public void dropdownCheckpoints_IndexChanged(int index)
    {
        checkpointsAmount = checkpoints[index];
        Debug.Log(checkpointsAmount);
    }

    public void NextButton()
    {
        traveling.ReadDropdowns(algorithmName, checkpointsAmount);
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
    }

    public void QuitButton()
    {
        Debug.Log("Quit!");
        Application.Quit();
    }
}

What I am missing here? Please help.

You may want to use a singleton pattern for menu, that way you can access the menu script from scene to scene without it being destroyed. Try this:

public static Menu instance = null;

private void Awake()
    {
        if (instance == null)

            //if not, set instance to this
            instance = this;

        //If instance already exists and it's not this:
        else if (instance != this)

            //Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GameManager.
            Destroy(gameObject);

        //Sets this to not be destroyed when reloading scene
        DontDestroyOnLoad(gameObject);
    }
1 Like

tl;dr: You can’t “talk to” objects in scenes that haven’t been loaded. It’s not possible to pass information between scenes in this way.

A null reference exception means you are trying to use a variable that doesn’t have a “real” value assigned to it. Usually that means you are putting a dot after the variable name, as in myVar.SomeFunction()

To get a null reference error on that particular line, the variable “traveling” would need to have a value of null.

Generally, a variable is null if you never assigned it a value, or if you assigned it to something that doesn’t exist.

Looks like you are initializing this particular variable on line 14:
traveling = GameObject.FindObjectOfType<Traveling>();
If the variable is null after that, it means that FindObjectOfType failed to find any objects of that type.

Which is because you are trying to grab an object from a different scene, but objects in a given scene do not exist until that particular scene is loaded. (This is the main point of splitting things into multiple scenes–so that they don’t have to all exist in memory at the same time.)

So you can’t “send” information into another scene, and the objects in that scene can’t “do” things before the scene is loaded. However, you can “remember” information through the process of changing scenes, so that it can be used in the new scene when it starts up. To “remember” information, you just need to put it in some object that doesn’t get destroyed when you load the new scene.

There’s two general ways to do this:

  • Call DontDestroyOnLoad on some Unity gameobject to prevent it from being destroyed when you switch scenes
  • Use static variables a non-Unity object (just a plain old C# object) to store the data. (You can also use regular variables inside a non-Unity object as long as you store a reference to that object somewhere–either in a static variable, or in a DontDestroyOnLoad object.)
1 Like

Thanks for your replies! If anyone is curious or struggles with the same problem, I’ve decided to go with static variables in Menu.cs (algorithmName, checkpointsAmount), and then I can read them in Traveling.cs by using Menu.algorithmName and Menu.checkpointsAmount.