简体   繁体   中英

Unity MissingReferenceException when loading same scene for second time

I'm trying to create Arkanoid 3d game using Unity with C#. I've created simple Menu (Scene 0), where I can start my game, my main scene where actual game takes place(Scene 1) and Scoreboard (Scene 2), which is shown after losing all 3 balls Player has at start. After pressing any key i go back to Menu and can start game again. And this is where problem begins.

During second game after loosing 1st ball, my game goes crazy. I get loads of "MissingReferenceException"s like one below (but some linked to other objects (like GUIText's etc):

MissingReferenceException: The object of type 'Player' 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.
Player.BallLost () (at Assets/Player/Player.cs:164)
GameEventManager.TriggerBallLost () (at Assets/Menagers/GameEventManager.cs:30)
Ball.Update () (at Assets/Ball/Ball.cs:47)

I noticed loads of MissingReferenceExceptions that are casued by not assigning variables. But this feels kinda diffrent for me since it all works perfectly during "1st play". What can cause this problem? I cheked in inspector after launching game for the second game and all variables are assigned to objects.

I'm not sure if shoudl insert game code since it has grown rather big and is split into >10 scripts.

I'm guessing you used Application.loadLevel(xx) . This is what I found out about it:

Reloading the scene should reset all the variables unless you are using static variables because logically creating a new instance of every object would reset its values to their initial state.

Static variables on the other hand are not destroyed because they are part of a class, not an instance. You have to reset these manually.

DontDestroyOnLoad() is a little different. It tells Unity not to destroy an object when you load a new scene. So these objects won't be reset either because they aren't being destroyed and recreated.

The only way to reset them is just to manually go through and turn the variables back to some initial state. It is your choice how you do that. You can either save all the initial values, or copy the values over from a newly instantiated class.

As an addition I'd like to say if you use static variables, it might be more useful to put them all in a Singleton or change them into non-static variables.

In my case, the problem were two static events. One assigned to call a method whenever it was raised (created by another class), and one created in this class to inform other classes for the occurance of something.

So I just added the following two in the OnDestroy() method:

OtherClass.onNewX_event -= X_eventHandler;

for the fist one (where OtherClass was the other class which was raising the onNewX_event and the current class was handlening it)

onThisClassEvent = null;

for the event created and raised in this class.

Include below function in your GameEventManager class

public static void Nullify(){
    GameStart = null;
    GameOver = null;
    LevelWon = null; 
    GamePause = null; 
    GameResume = null; 
    BallLost = null;

}

and call this function (GameEventManager.Nullify();) in Menu(scene0) before loading other scenes ;

GameEventManager.Nullify();
Application.LoadLevel("Scene1);

Hope this help...... :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM