- Home /
Losing object reference
Hi
I am currently trying to fix an issue where my GameManager which is set to not destroy on load has a reference to an object. The reference works correctly when I first run the game however the reference is lost when I reload the scene even though I have an initialisation method to recall the references as shown below. I'm fairly new to scripting so any help would be greatly appreciated.
Many Thanks
void Awake()
{
if (instance == null)
{
instance = this;
}
if (instance != this)
{
Destroy(gameObject);
}
DontDestroyOnLoad(gameObject);
sceneSetup = GetComponent<SceneSetup>();
InitGame();
sceneSetup.InitGame();
}
void InitGame()
{
playerAnimator = GameObject.FindGameObjectWithTag("Player").GetComponent<Animator>();
enemyAnimator = GameObject.FindGameObjectWithTag("Enemy").GetComponent<Animator>();
readyImage = GameObject.Find("ReadyImage");
drawImage = GameObject.Find("DrawImage");
calledDraw = false;
readyImage.SetActive(false);
drawImage.SetActive(false);
}
private void OnLevelWasLoaded()
{
level++;
InitGame();
sceneSetup.InitGame();
}
Answer by sarahnorthway · Jul 11, 2019 at 07:27 PM
Unity overrides the behavior of Null, so that any Component or GameObject that has been Destroyed will return true for "== null" and throw NPEs even if you still have a reference to it and it technically still exists in memory.
So the references may have been destroyed when the scene changed. I think player, enemy, readyImage and drawImage all need to be marked as DontDestroyOnLoad for them to persist.
So you'd need to call Awake again after the scene loads to find the new instances of each, and I don't think that happens for objects with DontDestroyOnLoad. This should trigger the manager to re-init when the scene is reloaded:
void Awake() {
Init();
SceneManager.sceneLoaded += Init;
}
void Init() {
if (instance == null)
{
instance = this;
}
...
Answer by BradyIrv · Jul 11, 2019 at 07:34 PM
My guess is that when you Initialize the GameManager from one scene, everything initializes as you want it to. The GameManager is then carried over to the next scene (and in doing so loses reference to the variables you are tracking because they are destroyed with the scene). However, what you are most likely mistaking is that the Awake function of an object that is DoNotDestroyOnLoad() does not get called when the next scene is loaded. The script has already been initialized (Awake), so if you want to gain reference to the variables again from a new scene, you will have to call your GameInit function manually when you load the next scene.
SceneManagement.LoadScene();
GameManager.GameInit();