0
\$\begingroup\$

I am trying to persist objects on scene loading, but the objects always get deleted when the scene does load.

LevelManager.CS

public void LoadLevel(string name){
    if (name == "Main")
    {
        SceneManager.LoadSceneAsync(name);
        GameManager.LoadState();
    }
    else
    {
        GameManager.SaveState();
        SceneManager.LoadScene(name);
    }
    Debug.Log("the scene is: " + name);
}

I placed the LoadScene method ontop in the hopes it would complete loading the scene before moving onto the next method call. In the next method call, I restore objects to their state.

GameManager.CS

public static void LoadState()
        { 
            ES3.Load<Dictionary<Vector2, Building>>("Buildings");

            foreach(Vector2 v2 in buildingPositions.Keys)
            {
                Building b = buildingPositions[v2];

                if(b.GetType() == typeof(Farm))
                {
                    newFarm = Instantiate(farmPrefab) as Farm;
                    Debug.Log("Build: " + newFarm);
                    newFarm.transform.position = v2;
                    Debug.Log(newFarm.transform.position);
                    newFarm.level = b.level;
                    **//newFarm.name = b.name;**
                    newFarm.levelText = newFarm.GetComponentInChildren<Text>();
                }
            }

            CheckTheCall();
    }

What actually happens is when the scene is changed, the LoadState code is run at the same time, which then causes my object to be deleted after the scene has finished loading, because its created before the scene changes.

The third last line "newFarm.name = b.name" gives me an error that newFarm was destroyed. The last line "CheckTheCall()" calls newFarm (which I declare at the top of the script to ensure scope wasn't the issue) and that shows newFarm exists as a farm. THEN after all this, the scene changes, so my instantiated object is deleted.

I'm so confused I tried with just SceneManager.LoadScene(name) but the result is still the same. It's like the entire function completes and then the scene loads.

Any ideas on how to get around this one? I need the objects to spawn back into the main scene in the same state they were.

\$\endgroup\$
  • \$\begingroup\$ Are you looking for something like Object.DontDestroyOnLoad ? \$\endgroup\$ – TomTsagk Apr 16 '18 at 13:43
1
\$\begingroup\$

LoadSceneAsync says explicitly "DO NOT wait for the scene to finish loading before proceeding to the next line." The Async stands for "asynchronous," meaning the load will happen in the background while the rest of your game keeps running, which helps you avoid a visible hitch, and can let you display progress or even have interactivity on your loading screen.

If you want to call a function after the load has completed, you can use the AsyncOperation.completed event:

public void LoadLevel(string name){
    if (name == "Main")
    {
        var asyncLoad = SceneManager.LoadSceneAsync(name);
        asyncLoad.completed += PopulateSceneAfterLoad;
    }
...
}

void PopulateSceneAfterLoad(AsyncOperation op) {
    GameManager.LoadState();
}
\$\endgroup\$
  • \$\begingroup\$ Thank you for responding Greg, just trying out your version, but getting an error for "completed" as there is no definition for it. Did you mean; if(asyncLoad.IsDone) PopulatedSceneAfterLoad(); \$\endgroup\$ – Anon Apr 18 '18 at 12:00
  • \$\begingroup\$ I just opened up Unity to try to replicate the problem, but completed seems to be defined as expected. I've updated the method signature above to include the AsyncOperation argument. Can you confirm what version of Unity you're using? \$\endgroup\$ – DMGregory Apr 18 '18 at 12:35
  • \$\begingroup\$ Hi Greg, Using 5.6.1f1. Not coming up on mine so had to use SceneManager.SceneLoaded and needed to add change it to PopulateSceneAfterLoad(Scene scene, LoadSceneMode mode) \$\endgroup\$ – Anon Apr 18 '18 at 13:16
  • \$\begingroup\$ That'll do. Feel free to add your own Unity 5.6 answer — it may help other users on that version. \$\endgroup\$ – DMGregory Apr 18 '18 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.