Static object losing references in the Inspector after loading

This topic pertains to Mike Geig’s Live Training video titled ‘Persistence - Saving and Loading Data’, which can be found here.

Basically, I’m using a gameObject called “GameManager” to persist game data across multiple scenes and this approach involves the use of what Mike refers in his video as the “Singleton”, which is often used in a more broader context within the Object Oriented Programming world.

Anyway, the GameManager script is attached to each Scene and I have several references to other game objects and components via the Inspector panel. Once again, these references are part of the GameManager script.

As for the GameManager script itself, I use the following code block to either keep or destroy the GameManager object accordingly:

public static GameManager manager;

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

When I load each individual scene manually there is no problem whatsoever; meaning all those references I created in the Inspector are intact and work correctly. But, when I load another scene using the Application.LoadLevel(1) method, the specified scene loads just fine, but all the references I created for the GameManager script get dropped.

I did some digging on this topic and came across this post, which appears to be somewhat related but I still can’t seem to fully understand how to work around the specific problem I have. Is adding references via the Inspector to the persistent object a bad practice, or am I just doing it wrong?

You should avoid having the same singleton object in each scene. That means you have multiple instances of that object each serialized into a different scene. Manager objects should never be inside a game scene. If you want to have a manager where you can assign references to, make sure you only load that scene once at start.

Also keep in mind if your singleton references other objects in the scene that are not persistent, those references will become null when you load another scene as all objects that has not been marked with DontDestroyOnLoad will be destroyed.

Placing the same singleton object in each scene makes no sense as your singleton code will get rid of the singleton that is loaded with the new scene since there is already one. However the old one might have lost it’s references.

If something persentent needs to access something that gets loaded dynamically you have to use GameObject.Find / FindObjectOfType / GetComponent to get those references.

Another way is a two way approach. Your GameManager is a real singleton which is only loaded once at start. But you simply use another class which is not a singleton but holds all important references in each scene. Your singleton object just has to find that one object in the scene and has access to everything that object references. You would have to place such an object in each scene and make sure you don’t mark it with DontDestroyOnLoad. It should be destroyed with the old scene since the references it contained are obsolete.

Here’s an example:

// GameManager.cs

public static GameManager manager;
public SceneData data;

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

void OnLevelWasLoaded(int aLevelID)
{
    // If a new level is loaded, find it's "SceneData" object in the scene
    data = FindObjectOfType<SceneData>();
}

And this could be the “SceneData” class:

public class SceneData : MonoBehaviour
{
    public GameObject player;
    public Camera sceneCamera;
    // ....
}

Now you can always use:

GameManager.manager.data.player

as long as every scene has a SceneData object which holds the references to other scene objects.

@CrucibleLab I’m having the same issue, and the one solution provided doesn’t really allow for data persistence! The whole idea is to move data between scenes -not merely to have an object present in all scenes.
Having each scene’s data in each scene -as stated above- doesn’t really solve the problem of moving the score, health, exp, weapons, etc… etc… between levels.
Till someone eventually answer this -if it ever gets answered- I guess PlayerPrefs -or alternatively and probably better- saving/loading provided in the same session of @mikegeig would be a solution. That means every scene will have to load all its info at the start, then save everything before it’s destroyed.
Much work for the platform to do, and I’m sure there’s a better way to do it, but till you can find it…