Getting "MissingReferenceException: The variable of doesn't exist anymore" error after calling Set

I’m seeing this weird issue in my project all of the sudden. I’m actually using a function from the Network Lobby package from the Asset Store. The code looks like this.

    public void ChangeTo(RectTransform newPanel)
    {
        if (currentPanel != null)
        {
            currentPanel.gameObject.SetActive(false);
        }

        if (newPanel != null)
        {
            newPanel.gameObject.SetActive(true);
        }

        currentPanel = newPanel;
    }

ChageTo() is supposed to turn the current panel off and switch the new panel on. But, when I call ChangeTo() and pass an instance of a panel, it throws the error message and I can’t set the panel active anymore. Does anyone have any idea what is going on here?

Thanks,

Mike

Are you destroying these panels anywhere? Perhaps you’re going from one scene to another, where the old panel belongs to the old scene?

That error usually happens when you’re trying to access a gameobject that’s been destroyed. I don’t see anything happening in the code you posted that could cause that, so it must be elsewhere in your project.

Everything is done in one scene. I should have included the rest of my code in my original post. ChangeTo() gets called in a button click handler like this.

public RectTransform mainPanel;

public void mainMenuButtonHandler()
{
ChangeTo(mainPanel);
}

As soon as currentPanel.gameObject.SetActive(false) gets called and turns the last panel off, the error happens. Not only does the old panel turn invisible. But, all references to it go away

Thanks,

Mike

I created a small test project that just included the button handlers and the ChangeTo() method. And, it worked fine. So, it looks like there is an issue with my project. To try to figure out what is going on, I added some debug logic. Now it looks like this.

    public void GameTabHandler()
    {
        Debug.Log("entered GameTabHandler()");
        ChangeTo(pnlGame);
        Debug.Log("leaving GameTabHandler()");
    }

    public void ChangeTo(RectTransform newPanel)
    {
        Debug.Log("entered ChangeTo()");
        if (currentPanel != null)
        {
            Debug.Log("setting currentPanel.SetActive(false) ");
            currentPanel.gameObject.SetActive(false);
            Debug.Log("done");
        }

        if (newPanel != null)
        {
            Debug.Log("setting newPanel.SetActive(true) ");
            newPanel.gameObject.SetActive(true);
            Debug.Log("done");
        }

        Debug.Log("currentPanel = newPanel;");
        currentPanel = newPanel;
        Debug.Log("leaving ChangeTo()");
    }

When I click my Game Tab button, my output looks like this.

entered GameTabHandler()
entered ChangeTo()
setting currentPanel.SetActive(false)
MissingReferenceException: The variable pnlCalibrate of VBTGame doesn’t exist anymore.

The rest of the method does not get executed. The rest of the script does continue to run though.

It appear that something about this game is breaking the SetActive() method. Does anyone have any ideas on how to troubleshoot this?

Thanks,

Mike

Modify your post to use code tags Using code tags properly - Unity Engine - Unity Discussions

Gets harder to follow longer scripts.

Your error suggest you are losing a reference to something and not an issue with SetActive.
Can you upload your test project here and perhaps we can tell you what is going wrong?

What is public void GameTabHandler()?

Is that a constructor? If so, change it to Awake().

public void GameTabHandler()

Is called by a button on the base panel.

It looks like the issue is due to a bug within Unity. My script works for one UI hierarchy but fails for another. I decided to go ahead and use a work-around. I will post what I did in case anyone else runs into the same issue I did.

I was trying to implement a tabbed-dialogue similar to the one used in the Network Lobby asset on the Asset Store here.

I tried using currentPanel.gameObject.SetActive(false) to turn the last panel off and use newPanel.gameObject.SetActive(true) to turn the new panel on. That usually works. But, in my case, the SetActive(false) method causes Unity to lose its reference to the panel the user is navigating away from. I found that the same script works fine on a simple UI hierarchy but has issues with more complex ones.

My solution was to write a script that avoids using SetActive(false) to turn UI panels off. Instead it moves unused panels off of the screen. i hate this work-around. But, its the only thing I could come up with given my time restraints.

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

public class UIDirector : MonoBehaviour {

    public RectTransform pnlCalibrate;
    public RectTransform pnlSetup;
    public RectTransform pnlGame;

    private Dictionary<string, PanelData> dctPanels = new Dictionary<string, PanelData>();

    /// <summary>
    ///
    /// </summary>
    void Start()
    {
        RegisterPanel(pnlCalibrate);
        RegisterPanel(pnlSetup);
        RegisterPanel(pnlGame);

        SwitchTo(pnlCalibrate);
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="rctPanel"></param>
    void RegisterPanel(RectTransform rctPanel)
    {
        dctPanels.Add(rctPanel.name, new PanelData(rctPanel));
    }


    /// <summary>
    /// This code fires with the Calebrate Panel Tab button is clicked
    /// </summary>
    public void ActivateCalibratePanelButtonHandler()
    {
        SwitchTo(pnlCalibrate);
    }

    /// <summary>
    /// This code fires with the Setup Panel Tab button is clicked
    /// </summary>
    public void ActivateSetupPanelButtonHandler()
    {
        SwitchTo(pnlSetup);
    }

    /// <summary>
    /// This code fires with the Game Panel Tab button is clicked
    /// </summary>
    public void ActivateGamePanelButtonHandler()
    {
        SwitchTo(pnlGame);
    }

    /// <summary>
    /// Moves all unused tab panels off of the screen.
    /// </summary>
    /// <param name="newPanel"></param>
    public void SwitchTo(RectTransform newPanel)
    {
        foreach (KeyValuePair<string, PanelData> kvpPanel in dctPanels)
        {
            PanelData pnl = kvpPanel.Value;
            if (pnl.transform.Equals(newPanel.transform))
            {
                pnl.MoveToOriginalPosition();
            }
            else
            {
                pnl.MoveOffScreen();
            }
          
        }
      
    }
}


using UnityEngine;

public class PanelData
{
    public RectTransform transform { get; set; }
    public Vector3 location { get; set; }
    public Quaternion orientation { get; set; }

    private Vector3 vctOffScreen = new Vector3(100000, 0, 0);

    public PanelData(RectTransform tran)
    {
        this.transform = tran;
        this.location = tran.position;
        this.orientation = tran.rotation;
    }

    public void MoveOffScreen()
    {
        Debug.Log(string.Format("moving {0} off screen {1} ", this.transform.name, vctOffScreen));
        this.transform.SetPositionAndRotation(vctOffScreen, Quaternion.identity);
    }

    public void MoveToOriginalPosition()
    {
        Debug.Log(string.Format("moving {0} to original position {1} ", this.transform.name, this.location));
        this.transform.SetPositionAndRotation(this.location, this.orientation);
    }

}

If you think you’re encountering a bug, I’d file a report. I’d personally would like to try and reproduce your issue, as I haven’t encountered anything like that before, even using a similar system that manages several different dialog boxes.

Glad you found a work around at least.

Thanks @Brathnann . I would upload my project if i could. Unfortunately, the group I am writing this for has a patent on the application. So, I’m not sure that I can upload it without getting into legal trouble.

I tried copying the project and chopping parts of it off to make something that I could upload. But, it began changing the behavior and I ran out of time.

Thanks again for the input.

FYI I got this error when I have a public GameObject I has on a script that I assigned via the inspector that I changed the type to transform. The object stayed there in the inspector, but the error occured.

6 Likes

Getting this in Unity 2021.3.11f1. I have a global gameobject with DontDestroyOnLoad() with global variables on it, and it decided to stop working on me all of a sudden

Anytime you destroy something that something else is still pointing at, and that something else accesses it, you get this.

If you think it wasn’t happening before because the earlier version of Unity didn’t do it, you are likely incorrect, and in any case, it’s not an excuse to start necro-posting to old threads for the simplest most common error in the entire world.

How to fix a NullReferenceException error

https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

Three steps to success:

  • Identify what is null ← any other action taken before this step is WASTED TIME
  • Identify why it is null
  • Fix that

In the future, please start your own new thread, but you never even have to post ANYTHING for a NullReference. Just use the above three steps and fix it.

I had the same problem. Not sure why. I made the inspector variables, then I created static singleton copies.
In Awake(), I copied the inspector ones, to the singleton ones. Then only used the singleton ones.
Fixed the problem. For some reason, the first line in Start() can use the inspector variable, but the second line says it has been destroyed.