Object reference missing during runtime without changes from script

My object reference, which is already assigned in the inspector, goes missing during runtime, even though I never assign the object through the script. How can this happen?

The GameObject is never destroyed by the script or even by the Unity callback, but it is still missing.

One thing I realized is that when the scene loads, all systems work properly. However, when I change the scene (e.g., to the main menu) and then go back to the Game scene, an error appears. I have no clue about the error, but if I run the code in Unity 2022 or earlier, the error doesn’t occur.

This usually means something persistent, usually DontDestroyOnLoad, is holding onto a reference onto something from the scene that was unloaded.

But mind you this could be editor specific.

Can you post the full error as text? (using code tags) Is the error even coming from your code?

Please don’t post code as screenshots either.

Here’s the error message I’m getting. The only script marked as Persistent (DDOL) is TimeManager.cs, I just want to clarify the reference for timerTextObject, so I included a screenshot of my code.

MissingReferenceException: The object of type 'UnityEngine.GameObject' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.Object+MarshalledUnityObject.TryThrowEditorNullExceptionObject (UnityEngine.Object unityObj, System.String parameterName) (at <44f3679c53d1477a9c6e72f269e3a3a9>:0)
UnityEngine.Bindings.ThrowHelper.ThrowNullReferenceException (System.Object obj) (at <44f3679c53d1477a9c6e72f269e3a3a9>:0)
UnityEngine.GameObject.SetActive (System.Boolean value) (at <44f3679c53d1477a9c6e72f269e3a3a9>:0)
BPH.Gameplay.UI.SpeedUpButtonUI.SpeedUp (System.Boolean value) (at Assets/_Project/Scripts/Gameplay/UI/SpeedUp/SpeedUpButtonUI.cs:78)
BPH.Gameplay.UI.SpeedUpButtonUI.OnSpeedUpTimerEnd (BPH.Core.Events.OnSpeedUpTimerEnd evt) (at Assets/_Project/Scripts/Gameplay/UI/SpeedUp/SpeedUpButtonUI.cs:52)
Litsch.EventSystem.EventManager+<>c__DisplayClass2_0`1[T].<AddListener>b__0 (Litsch.EventSystem.IGameEvent e) (at Assets/Litsch/EventSystem/EventManager.cs:37)
Litsch.EventSystem.EventManager.Broadcast (Litsch.EventSystem.IGameEvent evt) (at Assets/Litsch/EventSystem/EventManager.cs:82)
BPH.Core.TimeManager.Update () (at Assets/_Project/Scripts/Core/TimeManager.cs:44)

From the error it looks to be from your code then. Unity isn’t lying when it says the object has been destroyed.

Though mind you, you should never use ?., ?? or ??= operators with Unity objects (A good IDE would be warning against that). A normal null-check would guard against that correctly.

In any case, if it has been destroyed, it will show as ‘Missing’ in the object field. You need to figure out what that object is, and why its getting destroyed out from under this other component.

Is timerTextObject also a part of this DDOL TimeManager game object?

Is this maybe a prefab referencing a game object in the scene? This won’t work, prefabs can only retain/persist references to within themselves. Any reference outside the prefab needs to be obtained at runtime.

In all other cases, it’s what it says: timerTextObject has been destroyed (or one of its parents).

Sounds like a textbook example of a defectively implemented singleton.

There is never a reason to drag a GameObject into a scene if it will be DontDestroyOnLoad.

If you do, you are making a defective singleton:

  • you may drag it into something else that isn’t DDOL. FAIL
  • you may drag something else into it that isn’t DDOL. FAIL

Just DO NOT drag anything into a scene that will be marked DontDestroyOnLoad. Just Don’t Do It!

Some alternates, a simple Unity3D Singleton (no predefined data):

Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

These are pure-code solutions, DO NOT put anything into any scene, just access it via .Instance

Alternately you could start one up with a [RuntimeInitializeOnLoad] attribute.