Destroying Don't Destroy on Load

So in Laser Defender & Block Breaker Rick uses “don’tDestroyOnLoad” to keep the score & other elements transferring from scene to scene. Is there a way to destroy that on a certain scene?
What I mean is I need dontDestroy to work while I’m on stages 1-4 of Block Breaker & for Laser Defender. But on the congratulations, main menu & game over stages I’d like to destroy these gameObjects that are no longer necessary.
It’s probably more logical to only have them destroyed in the main menu but we’ll see.

Hi David,

Yes, that’s possible. :slight_smile:

Look up the sceneChanged delegate in the API and read the example. Then apply the example to your own project. You know if-statements, so you just have to figure out which scene was loaded. Check the SceneManager class in the API. You’ll find something that will solve this problem for you.

Good luck!


See also:

Thank you. By “The API” do you mean this site?

& if not what is “The API”???

Yes, that’s the API I meant. :slight_smile:

And I suggested to take a look at this:

I been working at it & I have an idea but I keep getting errors in the script. I tried various destroy.gameObject scripts but they not deleting the gameObject.
I’ve tried various else, if & else if statements but was unsuccessful. I’m sorry miss Nina but could you give me maybe another clue because I really don’t get what I’m supposed to see on the link you sent me.

If you already tested something, it would be great if you could share your code and the error messages and output in your console.

I really don’t get what I’m supposed to see on the link you sent me.

The example at the bottom. It’s relatively self-explanatory.

What I understood is that you want to destroy something in a specific scene. This means that you need to check something when a scene got loaded. And that something is: Which scene got loaded? Before you implement any complex logic, you just log the name of the current scene into your console after that scene got loaded. And when you load another scene, you do the same again. And where do you do that? In a script which is attached to one of your persistent game objects (that are supposed to get destroyed in a certain scene).

Step by step. Just keep it simple. Use the example from the API. If in doubt, copy and paste it as it is. Then log the name of the current scene into your console. And then share either the result or what you managed to do before you got stuck.

Once this works, the rest is not that difficult anymore.

Yep that’s what Windsands is trying to do. I’m working on what you said now.

My code is the ExampleCode on the API. The only thing the console tells me is:
There are 5 audio listeners in the scene. Please ensure there is always exactly one audio listener in the scene.

Have you been adding AudioListener when you’ve been meaning to add AudioSource? Usually the AudioListener is on the camera and it listens out for the noises and everything else makes the noises.

No. All of my sounds are based on how Rick taught “Laser Defender”. I really have no clue why that’s not working, why my Tile_Vainia coins are disappearing, & a few other things in my “Laser Defender Plus” game.
I try to spend at least 90 minutes figuring out the destroy the dontDestroyOnLoad thing.
So when I mess with the script @Nina sent me I get repeating stages that move slower & slower after I collide with the exit script (from Tile_Vainia).
Once I get that script working I’ll be able to publish a game I’ll be proud of.
Infact I don’t even know what an AudioListener is I only know how to use AudioSource.

Well that error you mentioned means there are multiple audio listeners in the scene, when you can only have one. Like most things in Unity, it’s a component.

I’m guessing you’re feeling a little overwealmed by Unity? Don’t worry, many do. And even when you think you’ve got it all figured out, something comes along and smacks you in the face. Forever learning. At least you’re sticking with it. It’ll be worth it when enough pieces fall into place.

Every time someone points you at a component, a term or a phrase you don’t understand, I want you to go and google it. If you find out it’s a component, try playing with it. Add it to a GameObject and see what it does. Maybe even write some code to see if you can interact with it in code. Whether it goes good or bad, it doesn’t matter. It’s a learning experience. Look at the Unity Docs and figure out how it works. If that doesn’t shed any light for you, go to youtube for a video or another source, like a forum.

This will occasionally send you down a rabbit hole. Sometimes you’ll get to the end and you’re more confused when you started, but those times it doesn’t, those pennies that drop into place make it worth it. The more you do stuff like this, the more you’ll learn and the faster your learning will snowball. You might not understand everything the first time around, but everytime you learn a piece of the puzzle, the other pieces become easier to learn and previous pieces become clearer.

Another technique I’d like you to try (until you feel you’ve got the hang of it) is to watch a video through without typing any code. Get a look at it. See what’s happening. Try to learn by observing. You might need to watch a few videos, or even a section. When you think you know what’s going on, then go back and type in the code. I’m not sure this will work for you, but when learning, so many can’t see the forest for the trees.

Also consider doing a bunch more courses. There’s heaps of them out there. I’ve completed a stupid amount of them during covid, not to mention the collection of half finished courses. Not to mention heaps of unfinished games/prototypes. Keep at it.

1 Like

This sounds as if there might be an endless loop. Maybe a new scene gets loaded over and over again. Maybe each of the scene contains a persistent game object. Maybe one of those persistent game objects is the camera with the AudioListener.

If you just copied and pasted the example code, you should have seen the Debug.Log messages from the example in your console. The example code does not load or modify anything, so it should not make your game slower.

So I been working at this as usual a min of 90 min per day. Then I looked at Rick’s “Laser Defender” 2018. What I don’t understand is (I have to describe sorry):
When I play Rick’s Laser Defender & Block Breaker 2018 the score text (& health text) is where is belongs & flows from stage to stage. Then in the game over carries over to show the player his/her score. Then if I hit replay, the score (& health) reset due to this part of Rick’s code.
… private void SetUpSingleton()
{
int numberGameSessions = FindObjectsOfType().Length;
if (numberGameSessions > 1)
{
Destroy(gameObject);
}
else
{
DontDestroyOnLoad(gameObject);
}
}…
Then here is the part where I don’t understand but will solve my problem. When I go to the main menu the score text disappears even though it’s part of dontDestroyOnLoad. This is actually better then what I was trying to do but my problem is I don’t understand why that happens I don’t know what screenshots or scrips I could show you to show you what the problem is because I don’t know. But if I could do that it would be better then what I wanted to do & I could focus on other aspects of “Laser Defender Plus”.

Hmmm so I also see:
… public void ResetGame()
{
Destroy(gameObject);
}
&
public void LoadGame()
{
SceneManager.LoadScene(“Game”);
FindObjectOfType().ResetGame();
}…
Are connected. I think I’m onto something.

Check if your “singleton” calls gameObject.SetActive(false); in the same if-block where Destroy(gameObject); gets called. If there isn’t that line of code, add it. Destroy() does not destroy immediately. FindObjectOfType could still find the “destroyed” game object.

When I go to the main menu the score text disappears even though it’s part of dontDestroyOnLoad.

Does it get destroyed or does it just contain an empty string? It is still possible to destroy “DontDestroyOnLoad” objects with the Destroy method.

Do you understand the concept of a singleton? If so, and if you feel that Rick’s singleton implementation causes unsolvable problems with your own ideas, you could try to replace it with another singleton version (first version, remove the sealed keyword, replace Singleton with your classname). You are not obliged to keep his code. His code solves his problems, not necessarily yours.

I think I’m onto something.

Yes, the two methods are connected. In the LoadGame method, you could try to swap the two method calls to ensure that ResetGame gets executed. Maybe LoadScene terminates the LoadGame method early and prevents ResetGame from being called in your case.


See also:

I know very little about Singletons. But what I’ll do is search for videos on it. Are there any that you would suggest because I’m sure there’s thousands?
I tried this with Laser Defender (base) but I need to test it with TileVainia & Shape (not block) Breaker.
If this works I can have the game done this week & then ask you guys for help posting I assume the webex or whatever it’s called version.
Ohhh I just noticed a link you sent me I’ll read it now.
Thank you.

Well, the purpose of a singleton is to ensure that there is only one object of a kind. That’s all.

In Unity, we do not have a real singelton because all objects in the Hierarchy get created. We need to destroy the superfluous ones. That’s not the actual singleton pattern because our code does not and cannot prevent the superfluous objects from being created in the first place. So Rick’s code is rather a “singleton”.

Another typical “singleton” version in Unity is this (plus the implementation for checking in which scene we are when a new scene gets loaded, and we destroy the game object if we are not in the “correct” scene):

using UnityEngine;
using UnityEngine.SceneManagement;

public class Singleton : MonoBehaviour
{
    static Singleton instance = null;
    int startingSceneIndex;

    void Start()
    {
        if (!instance)
        {
            instance = this;
            SceneManager.sceneLoaded += OnSceneLoaded;
            startingSceneIndex = SceneManager.GetActiveScene().buildIndex;
            DontDestroyOnLoad(gameObject);
        }
        else if (instance != this)
        {
            Destroy(gameObject);
        }
    }

    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        if (startingSceneIndex != SceneManager.GetActiveScene().buildIndex)
        {
            instance = null;
            SceneManager.sceneLoaded -= OnSceneLoaded;
            Destroy(gameObject);
        }
    }
}

Theoretically, if you copied and pasted the code example from the Unity API, your current code should look similar to this (minus the “singleton”).

this refers to the current instance/object.

So what I learned about gameDev is solve on problem & create 2-3 more but somehow we enjoy this. Anyway do you have any idea why my ScenePercist.cs labeled items are not there anymore? Meaning my Tile_Vainia coins appear on my screen but not in my game levels.

Nevermind on that. I still have the scene persict but the dontdestroyonload is still not right. I want to focus on that.

That’s a good description of game development. :wink:

Meaning my Tile_Vainia coins appear on my screen but not in my game levels.

What do you mean by “on my screen”? In the Scene window but not in the Game window? If the coins are in the Hierarchy during runtime, it might be that they are rendered behind another sprite. Check the z-positions and make sure your different layers (background, foreground, coins, etc.) do not share the same z-position.

I still have the scene persict but the dontdestroyonload is still not right. I want to focus on that.

That’s a good idea. :slight_smile:

A little hint: The script I posted in my previous answer is what I used in the old version of the Tile Vania project to destroy the “persistent” coins that are supposed to get destroyed in other scenes but not in the current one. I just renamed the class so it is not that obvious.