I have a main menu, and a game level. If the game is lost, the main menu should load (via application.LoadLevel("...") ) and if "start game" is selected the level loads (again) also via application.LoadLevel. Well everything works perfectly fine the first cycle. But if the game is lost the 2nd time, I get a MissingReference.
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
and here is the code where the error is caused
private void endTheGame(){
alive = false;
Destroy(Player);
mainCamera.animation.Play("CameraDeath");
}
In the inspector I can see that the "mainCamera" variable is filled with the maincamera gameobject so it cant be null actually. What I think is that the script is still trying to access the first instance of the camera and not the second which was created during the reload of the level. But I have no idea how this can happen. I also use the c# messenger to call the endTheGame() function. dont know if that makes any difference.
All I found on google was that people have this kind of problems when they use " DontDestroyOnLoad" but I am not using it anywhere in my scripts. And I got the same problems when I tried to start a coroutine instead of the animation, so I doubt that the Animation.play is a problem.
Just in case this is the complete script
using UnityEngine;
using System.Collections;
public class GameMaster : MonoBehaviour {
public GameObject baseCamera = null;
public GameObject mainCamera = null;
private GameObject Player;
private GameObject Base;
public bool baseAlive = true;
public bool alive = true;
void OnEnable() {
// Remove listeners
Messenger.AddListener("Player killed", endTheGame);
Messenger.AddListener("Base killed", BaseDown);
}
void OnDisable() {
// Remove listeners
Messenger.RemoveListener("Player killed", endTheGame);
Messenger.RemoveListener("Base killed", BaseDown);
}
// Use this for initialization
void Start () {
Player = GameObject.Find("tps_player");
Base = GameObject.Find("Base");
baseCamera.camera.enabled = false;
(baseCamera.GetComponent(typeof (AudioListener)) as AudioListener).enabled = false;
Messenger.AddListener("Player killed", endTheGame); //messenger in enemy AI
Messenger.AddListener("Base killed", BaseDown); //messenger in enemy AI
}
void Update(){
if(alive == false){
if(!mainCamera.animation.IsPlaying("CameraDeath")){
backToMainMenu();
}
}
}
private void endTheGame(){
alive = false;
Destroy(Player);
mainCamera.animation.Play("CameraDeath");
}
private void BaseDown(){
baseAlive = false;
Debug.Log("The Base is gone, no more upgrades for you");
Destroy(Base);
}
private void backToMainMenu(){
Application.LoadLevel("mainMenu");
}
}
Just tested the above idea... Turns out in my case it was indeed my use of the Messenger class that was the problem. All I had to do was ensure that each of my 'Messenger.AddListener("whatever", FunctionName);' in Awake() simply needed to be properly matched with a 'Messenger.RemoveListener("whatever", FunctionName);' in OnDestroy(). Simple oversight and simple fix :)
– RoddieKieley