- Home /
DontDestroyOnLoad error
So I am using DontDestroyOnLoad for my options and this is the DontDestroyOnLoad code:
using UnityEngine;
using System.Collections;
public class dontdestroy : MonoBehaviour {
// Use this for initialization
void Start () {
}
void Awake() {
DontDestroyOnLoad(this);
if (FindObjectsOfType(GetType()).Length > 2)
{
Destroy(gameObject);
}
}
}
this makes sure that the object is being deleted if it is duplicated. Now, when i load first scene and go back to menu to try and load options. I get an error:
MissingReferenceException: The object of type '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.
This is the script I am using to display the options:
public void AccessOptions (Object myObject) {
GameObject.Find("Options").GetComponent<optionsprompt>().OptionsMenu.SetActive(true);
}
Answer by Superrodan · Jan 21, 2015 at 10:46 AM
When you return to the menu you will have duplicate objects.
Both objects have this code on them:
if (FindObjectsOfType(GetType()).Length > 2)
{
Destroy(gameObject);
}
What I believe might be happening is that both objects are determining that there are more than one of them and both objects are deleting themselves.
Instead, you might want to take a different approach to making sure only one exists. Here is some code I wrote for a music player that might help:
public GameObject musicPlayer;
void Awake() {
//When the scene loads it checks if there is an object called "MUSIC".
musicPlayer = GameObject.Find("MUSIC");
if(musicPlayer==null)
{
//If this object does not exist then it does the following:
//1. Sets the object this script is attached to as the music player
musicPlayer = this.gameObject;
//2. Renames THIS object to "MUSIC" for next time
musicPlayer.name = "MUSIC";
//3. Tells THIS object not to die when changing scenes.
DontDestroyOnLoad(musicPlayer);
}else{
//If there WAS an object in the scene called "MUSIC" (because we have come back to
//the scene where the music was started) then it just tells this object to
//destroy itself
Destroy(this.gameObject);
}
}
For some reason, when I use this my objects delete automatically when the first scene is loaded
I forgot a necessary piece, I apologize. Try this:
public GameObject musicPlayer;
void Awake() {
//When the scene loads it checks if there is an object called "$$anonymous$$USIC".
musicPlayer = GameObject.Find("$$anonymous$$USIC");
if(musicPlayer==null)
{
//If this object does not exist then it does the following:
//1. Sets the object this script is attached to as the music player
musicPlayer = this.gameObject;
//2. Renames THIS object to "$$anonymous$$USIC" for next time
musicPlayer.name = "$$anonymous$$USIC";
//3. Tells THIS object not to die when changing scenes.
DontDestroyOnLoad(musicPlayer);
}else{
//If there WAS an object in the scene called "$$anonymous$$USIC" (because we have come back to
//the scene where the music was started) then it just tells this object to
//destroy itself
if(this.gameObject.name!="$$anonymous$$USIC")
{
Destroy(this.gameObject);
}
}
}
$$anonymous$$eep in $$anonymous$$d it is important that in the above example your music player is not called "$$anonymous$$USIC" in the inspector before you press play. The logic basically says "If an object named $$anonymous$$USIC doesn't exist, change my name to $$anonymous$$USIC and keep me around forever".
The idea is that the first time you load a scene $$anonymous$$USIC won't exist but when you leave and come back it will so $$anonymous$$USIC will save itself but the copy (which is not called $$anonymous$$USIC) will delete itself.
Still happening: this is what happens when i click play (gif) http://gyazo.com/2dea37ed9fc368c44118f07afb7414eb
When you copied my code did you change the word "$$anonymous$$USIC" to something else? If so, what?
Of course heres what I changed it to:
Options = GameObject.Find("Options");
if (Options == null){
//if object doesnt exist then it will set the script attached to optionsobject
Options = this.gameObject;
//renames the object to "Options for next load
Options.name = "Options";
//tells this object to not die when changing scene
DontDestroyOnLoad(Options);
} else {
//destroy itself
if(this.gameObject.name != "Options")
{
Destroy(this.gameObject);
}
}
also it seems that it doesnt bring the object over to my other scenes
Answer by hav_ngs_ru · Jan 19, 2015 at 04:41 PM
check what exactly is null here?
GameObject.Find("Options") ?
GameObject.Find("Options").GetComponent() ?
GameObject.Find("Options").GetComponent().OptionsMenu ?
I guess first is null. In this case it means you have no objects named "Options" in your scene. Unfortunately code you posted doesnt tell anything about object names and about what is "optionsprompt", so its hard to detect what is wrong...
is there object named "Options" in your scene? is it active?
is it placed to scene in editor or instantiated runtime?
is your "dontdestroy" script attached to it? is script active?
what is the "optionsprompt" script? what it attached to? is script active?
@hav_ngs_ru http://i.gyazo.com/9f40b6418a2d6f20bd0a3b3228f60e0b.png yes they are both there but it doesnt want to open it up which I really dont understand why
click to Options object and make screenshot of it's components in editor
@hav_ngs_ru http://i.gyazo.com/1113cee0dd5d267671c70fd687a2e79f.png dont worry about the btn objects in the optionsprompt component. they are going to be removed (nothing is actually in them from the start. The hierarchy shown was doing the go to level1 then back to menu (which my options breaks and doesn't want to open)
unfortunately I still cant seeon screenshot: does Options object have "optionsprompt" script attached?
and didnt you check - what exactly return null?
GameObject.Find("Options") ?
GameObject.Find("Options").GetComponent() ?
GameObject.Find("Options").GetComponent().Options$$anonymous$$enu ?