About 'Remembering Pickups'!

In this video (objectives)…

  1. Create a scene persist script that uses a singleton pattern to not destroy any children objects (such as pickups).
  2. Within our scene persist, check if the current build index differs to starting build index.
  3. Destroy scene persist object if we move on to the next level.

After watching (learning outcomes)…

Create a system to allow objects to remember their state within a scene.

(Unique Video Reference: 32_TV_CUD)

We would love to know…

  • What you found good about this lecture?
  • What we could do better?

Remember that you can reply to this topic, or create a new topic. The easiest way to create a new topic is to follow the link in Resources. That way the topic will…

  • Be in the correct forum (for the course).
  • Be in the right sub-forum (for the section)
  • Have the correct lecture tag.

Enjoy your stay in our thriving community!

1 Like

Hi Ben,
I’ve found a down side in our scene persist schema: when loading next level (say level 2 from level 1) where another scene persist object exists (with its pickups child), this one immediately destroys itself because of the awake method that finds the level 1 scene persist object, which then destroys itself because of update method, since its starting scene index is different from current loaded scene index.
Still trying to work this around, you probably already knew this and preparing a fix in upcoming lessons, if not… help is welcome from anyone :wink:

thanks & keep up the great work
ciao
Marco

I noticed this as well. The problem is that this code needs to realize when you switch levels and then allow the change to take place the first time (per level). Give a look at my solution available at https://github.com/GaryThomas/TileVania.git

Good luck

1 Like

Thanks for sharing mate, trying this and let you know , at first glance it looks like the right solution :wink:

Just tried it, works like a charm, thanks again!

Hmmm…when I load the 2nd level the coins don’t appear until I lose a life and it reloads the player.

Edit: Wait a minute, I realised when I load a new level the Scene Persist object isn’t there until I lose a life. Is that correct behaviour?

Edit 2: Seems my startingSceneIndex isn’t being updated on level load, only when the first life is taken in a new level. Is this a problem anyone else is having, or have I done something silly?

To address the same problem @MarcoSbuAmabili had, I changed my ScenePersist Awake() function to be a little smarter. May not be as elegant as what @GaryThomas did, but it seemed to fit in a bit easier with what the lesson code was like.

private void Awake() {
    startingSceneIndex = SceneManager.GetActiveScene().buildIndex;
    if (FindObjectsOfType<ScenePersist>().Length > 1 && SceneManager.GetActiveScene().buildIndex != startingSceneIndex) {
        Destroy(gameObject);
    }
    else {
        DontDestroyOnLoad(gameObject);
    }
}

The most simple solution, without changing Ben/Rick code.
Add the following line of code, just before to load the next level.

Destroy (FindObjectOfType<ScenePersist> ().gameObject);

Finally, if you want a singleton just for one scene, create it as usual and destroy it at the end of level.

After a good night’s sleep. I have a corrected version of the scene persist class.
You no longer need to add the line of code for destroy gameObject.

using UnityEngine;
using UnityEngine.SceneManagement;

public class ScenePersist : MonoBehaviour
{
    int startingSceneIndex = -1;

    public int GetStartingSceneIndex ()
    {
        return startingSceneIndex;
    }

    void Awake ()
    {
        startingSceneIndex = SceneManager.GetActiveScene ().buildIndex;
        ScenePersist[] scenePersists = FindObjectsOfType<ScenePersist> ();
        if (scenePersists.Length <= 1) {
            // I am alone
            DontDestroyOnLoad (gameObject);
        }
        else {
            bool destroyMe = false;
            // We are Two
            foreach (ScenePersist scenePersist in scenePersists) {
                if (scenePersist != this) {
                    // It's not me
                    if (scenePersist.GetStartingSceneIndex () != startingSceneIndex) {
                        // You have nothing to do here
                        Destroy (scenePersist.gameObject);
                    }
                    else {
                        // I have nothing to do here
                        destroyMe = true;
                    }
                }
            }

            if (destroyMe) {
                // Seppuku!
                Destroy (gameObject);
            }
            else {
                // They are all dead, I will survive!
                DontDestroyOnLoad (gameObject);
            }
        }
    }

    void Update ()
    {
        int currentSceneIndex = SceneManager.GetActiveScene ().buildIndex;
        if (currentSceneIndex != startingSceneIndex) {
            DestroyObject (gameObject);
        }
    }
}

2 Likes

Privacy & Terms