The object of type X has been destroyed but you are still trying to access it.

Still getting nowhere with this.
Although I did have a ‘doh’ moment.

I was loading a mainmenu scene. Then opening my scene2.
In scene2 I was running the levelgenerator to create a list of levelPieces.
That was all working, my issues was when I came back to the mainmenu and I got the object destroyed message.

Then it dawned on me that in my mainmenu I hadn’t created my levelpiece or levelGenerator object, beacuse I dont need them there, its not part of the game. But I guess if they aren’t there, it cant keep them alive.

So I tried creating the LevelPiece object and the LevelGenerator object in my main menu also.

Now this means when I run the main menu, I get all my levelpieces created (on my menucanvas by default, I’ll need to move them onto my other canvas for display later)

However, when clicking the button to go through to scene2 it dies with my favourite error message.

MissingReferenceException: The object of type ‘LevelPiece’ 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.

It does this as soon as any object in scene2 tries to access the List that was created in the menu scene, eg

    void MoveTowards(){
        float step = speed * Time.deltaTime;
        // Check to make sure we should be moving towards
        if (LevelGenerator.instance.pieces[currentTarget].displayOnly == true){
            // Move on to next piece
            IncrementCurrentPiece ();
            }
            target = LevelGenerator.instance.pieces[currentTarget].transform.position;

So where previously I was creating the List of objects in scene2 and they were vanishing when going back to mainmenu, I’ve now got the opposte issue in that they create in mainmenu scene and die when going to scene2.

I’m sure there is something really simple stopping this from working, but I have no idea.
Can someone please look at this code and let me know what I’m doing wrong. I know its a silly newbie mistake, but I cant work it out. I tried splitting it as below so the declaration only is done in mainmenu, and in scene2 it does all the work on it, but it still seems to fail.

I just dont know how to keep this list of object persistant through the 2 scenes.

Please help me. This is driving me mad now.
Thanks

LevelGenerator Class:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LevelGenerator : MonoBehaviour {
    public static LevelGenerator instance;
    public Transform levelStartPoint;
    public  List<LevelPiece> pieces = new List<LevelPiece> ();
    public  List<TextPiece> textPieces = new List<TextPiece> ();
    public LevelPiece LevelPiece;
    public TextPiece TextPiece;
    private StandardVars standardVars = new StandardVars();
    private int lastPiece;


    void Awake() {
        if (instance == null) {
            DontDestroyOnLoad (gameObject);
            instance = this;
        } else {
            if (instance != this) {
                Destroy (gameObject);
            }
        }
    }

    void Start () {
        if (Application.loadedLevel ==0) {
            //lastPiece = 0;
            GenerateInitialPieces ();
            GenerateTextPieces ();
            PrintValues ();
        }
        if (Application.loadedLevel >=1) {
        //Debug.Log ("Calling Sprite Update");
            UpdateSprites ();
        }
            }

LevelPiece CLass

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LevelPiece : MonoBehaviour {
    void Start () {
// Just variable definitions
etc
etc
    }
    
    // Update is called once per frame
    void Update () {
        
    }
    void Create () {

    }
}

So, I think maybe I know what’s wrong now that I’m reading this, again.

The list of objects are just on their own, right? If you want the list of objects to persist, they must either be parented to a root game object that has DontDestroyOnLoad (or they themselves must have DontDestroyOnLoad).
Having them in a list, on a game object using DontDestroyOnLoad, is not enough to keep them around.

Thanks, that sounds quite possible.
The list is just created within my LevelGenerator class, as any other variable would be - as above.

Unfortunately I’m way out of my depth and dont quite understand exactly what you mean by 'parented to a root gameobject"

I’ve tried a few things, but not got anywhere.

And is it the list I need to parent (i.e. pieces) , or is it the objects in the list i.e. LevelPiece?

Are you able to point me at any tutorials to this? I’ve tried google but not found anything of use, that I understand.

Incidentally, I tried adding:

void Awake(){
        DontDestroyOnLoad(this.gameObject);
    }// Use this for initialization

to my levelpiece.cs script.
My exit button from scene2 now goes back to the main menu, without error. On the surface this seems a good thing.
My LevelPieces seem to remain intact, but I cannot click anything on the main menu.

I cant tell if this is good news or not. It looks like debug messages from scene2 are still being written, indicating that even though I am back at the mainmenu screen visually, I am actually still running components of scene2.

In fact, if I stick a some Debug.Log output on the start game button of the main menu, clicking it doesn’t even output anything. So its like it never actually returns back from my scene2.

One other thing, I’m still using Application.LOadLevel. Is that likely to be causing issues now it has been superceded by SceneManager.?

Thanks

I would switch to SceneManager just because. I don’t think that would break anything, but I would stop using it ( get out of the habit) :slight_smile:

Okay, so what I was suggesting was that you could put that DontDestroy on each piece, or you could add every piece to 1 (say empty gameobject), as a child.
Root, meaning it has no parent game object. Only root game objects can execute “DontDestroyOnLoad” (but take their children with them… if that makes sense lol)

Let’s say your code may be working, if I were you maybe I would try to hide the parent object (or each one individually, if you don’t parent them) when you load your menu scene or whatever.
Then , see if you can interact properly with said scene.

  • hide … disable… whatever. :slight_smile:

Thanks once again.

I’ve changed to SceneManager but it is just the same.

Just stepping back and trying to think this through a little.

Several days ago I responded to this thread because I was getting the error about objects being destroyed when I went back to the main menu.

So we’ve spent several days getting my objects to persist so they don’t get destroyed when I go back to the main menu, and I don’t get the error.

But now we have the issue where I go back to the main menu and it doesn’t respond, yet I can still see functions and objects of my scene2 working in the background and writing to Debug.Log. So it looks like it has visually gone back to my menu, but scene2 hasn’t closed down.

So actually, and correct me if I’m wrong, the issue isn’t around scope and not destroying objects, its because scene2 isn’t fully unloading when I move back to the menu? Is that not my ‘real’ issue here?

The docs seem a little sparse, but from what I can find:

It does mention:
Ghost scenes. Every time you load a new level with SceneManager.LoadScene, Unity flushes all the scenes that have been previously loaded. Only game objects that invoked DontDestroyOnLoad (documentation) survive the process. This means that you can potentially use LoadScene, yet having all the previous scenes still loaded. Despite this, Unity will fail to realise that those scenes are actually still alive.

I’ve no idea whether I’m seeing that issue, or whether I’m just misunderstanding what the scene opening and closing should do, and how it works.

As a beginner I’m pretty amazed that I’ve learned enough to get my game working (by developing it effectively in scene2) then I’m having all this trouble simply adding a main menu with ‘Start Game’ on the front of it. That would seem to be basic functionality.

So I’m even more confused than ever.
EDIT: On reflection, I wonder if I’ve made too much stuff not destroy, trying to get around the initial issue. In particular my player/aeroplane sprite is now a singleton and not destroy. Perhaps it just needs to be singleton without the donotdestroy, and that is holding things open. More stuff to play with tonight, although I’m still confused that adding a menu is is as troublesome as it has been. All I really want is an option to just close everything down and start again. I’d be happy.

Finally I have some good news :slight_smile:
For me, and possible even more so for you guys:smile:

It seems I was right on my previous post, and I’ve overdone the DontDestroyOnLoad stuff.
The UIManager script on the menu was the issue causing the button not to work when it went back.
So I left as singleton but commented the dontdestroy line and thats working.

Scene2 was still doing the updates on the console so I then went round the other stuff I’ve done, and removed from there, and that also didn’t break anything.

So after all that, it looks like it was just the individual levelPieces that needed dontdestroy on load. Looks like I made it worse by trying to add others rather than better.

I cant say I fully understand, but most importantly it is working.

Many thanks again, and hopefully for a last time. I really appreciate the time you’ve taken to help with this issue.

lol after reading all of that, I’m glad that you arrived at a working solution. Good stuff :slight_smile:

Unfortunately the next stage will be moving a lot of the level generation into the main menu, so I can have multiple levels and control over them.

I have a bad feeling I may have similar issues again but at least I have a slightly better grasp of how this works now.

Wish me luck …

Keep only what you need and perhaps if it gets to be too much, it might be an option to save & reload it (if the scenes aren’t all active at once, anyways).

Whatever happens – Good luck :slight_smile:

Thanks.

I don’t actually need to keep much between levels at all, and I had already considered saving it out from the menu and loading it back in at scene2. It seems a bit silly, but I suspect that is the best way to do it.

To recap, I have a level generator on scene2, which is just hard coded creating items in a list. I’m at prototype stage now.

What I need to do now is on main menu have a ‘select level’ option where I can pick one of say 10 levels and create a list of gameitems for use in scene2.

The level generator on scene2 will then have to be amended so instead of creatng a list of items based on hard coded values it either a) reads the list of items from the list variables in the main menu scene and duplicate them into its own list or b) reads them in from disk if I save the list temporarily to disk from the main menu.

Given the issues I had with stuff persisting and/or not persisting I’m inclined to just select the level and save the pieces out to disk on the mainmenu scene, and then just read it all in from disk on the scene2 game scene. I can treat the two as almost completely separate then, and just destroy everything in scene2 when we go back.

Is there anything radically wrong with that approach? I like it as once I’ve amended scene2 to create the list of objects from disk rather than from card coded values, I can leave that alone and not risk breaking it by adding functionality to the main menu.

Thanks once again for the input, you truly have the patience of a saint. :smile:

I see. I didn’t realize that only one of the levels would be keeping data, and just between the main menu and itself (though it may be reading data from another level).

To be honest, I don’t totally understand what you’re saying. 1 of 10 levels can decide what is built in scene2 - that’s what I understood. If by any chance those are just ‘values’ (not game objects), that makes things easier, as you can simply ‘bring’ that information with you when you go to scene 2.
If it’s just the active scene you want to keep active, as you transition from scene 2 to the menu (and back), then keeping the items in DontDestroy sounds perfectly okay (and hidden).

If you plan to save between play sessions, also, though, you will want to know how to save the current game, anyways.

Sorry I’m not always understanding everything right away. I’m certain it’s all crystal clear to you :slight_smile: heh.

As for always saving vs. keeping some things not destroyed (you said it’s not even a lot), I would say that between scenes, and if it’s not a lot, the difference is minimal; at the same time, though, there’s nothing to be scared of of keeping it not destroyed…

Hope that semi-complete, semi-vague response helps a bit lol

You and me both unfortunately.
I’ll have a play and look at my options.

I think my problem is I’ve gone full on into a project, as a first project, without having had the time to really get to grips with Unity, c# or programming in general. In an ideal world I would have had more time to spend on the basics and groundwork, but such is life.

I’m always recommending that to people :slight_smile: heh.

I understand wanting to dive in. Happens to me, too. But taking some time to build up helps a lot…

1 Like

Hello, i have same issue. after reload scene, some object missing reference. Please tell me your skype name @methos5k

Hey guys,

This is observer pattern, the event is still looking for the subscribed object.

Simply unsubscribe when you no longer need it to avoid errors.

private void OnDisable()
{
SomeClass.ThingsYouAreListeningFor -= MethodSubscribing;
}

2 Likes

+1 YaserDev. Was looking for that one for ages!

1 Like

Thanks to all who mentioned unsubscribing to event listeners. Doing that on my GameManager right before reloading the scene fixed this problem for me.

This actually saved me from a bunch of issues, thank you so much!!

1 Like

FWIW - I’ve been having this problem as well and solved it with what I think is a rather simple solution.
When the object gets destroyed - simply remove the the listener:

    void Start()
    {
        Object.onEvent += event;  
    }


    void OnDestroy()
    {
        Object.onEvent -= event;
    }

This is most likely the cause of the problem. Another alternative is to add/remove the listeners on the “OnEnable” or “OnDisable”