Search Unity

Instantiating objects only after scene has been loaded

Discussion in 'Scripting' started by Deeblock, May 4, 2018.

  1. Deeblock

    Deeblock

    Joined:
    Feb 14, 2018
    Posts:
    49
    I'm trying to spawn in objects into the scene from a save file. All the logic is done through my "GameManager" script which is a singleton and persists across both scenes. When transitioning from my main menu to the main level, I call
    Code (CSharp):
    1. SceneManager.LoadScene("main_level");
    However, this totally screws up my entire saving and loading methods.

    Code (CSharp):
    1. public void LoadGame()
    2.     {
    3.         SceneManager.LoadScene("main_level");
    4.         string jsonData;
    5.         if (newGame) // Start new game
    6.         {
    7.             var defaultPath = Application.streamingAssetsPath + "/Default/Default.json";
    8.             if (File.Exists(defaultPath))
    9.             {
    10.                 jsonData = File.ReadAllText(defaultPath);
    11.                 gameData = JsonUtility.FromJson<GameData>(jsonData);
    12.             }
    13.             else
    14.             {
    15.                 Debug.LogError("Save file is missing at: " + defaultPath);
    16.             }
    17.         }
    18.         else if (File.Exists(path + "/" + saveName))
    19.         {
    20.             jsonData = File.ReadAllText(path + "/" + saveName);
    21.             gameData = JsonUtility.FromJson<GameData>(jsonData);
    22.         }
    23.         else
    24.         {
    25.             Debug.LogError("Save file is missing at: " + path + "/" + saveName);
    26.         }
    27.  
    28.         /* Instantiate required objects */
    29.  
    30.         // Trees
    31.         var treeParent = new GameObject("Trees");
    32.         foreach (TreeSaveLoad.TreeData tree in gameData.trees)
    33.         {
    34.             var treeType = oakTree;
    35.             switch (tree.type)
    36.             {
    37.                 case (TreeSaveLoad.TreeType.Redwood):
    38.                     treeType = redwoodTree;
    39.                     break;
    40.                 case (TreeSaveLoad.TreeType.Birch):
    41.                     treeType = birchTree;
    42.                     break;
    43.                 case (TreeSaveLoad.TreeType.Beech):
    44.                     treeType = beechTree;
    45.                     break;
    46.                 case (TreeSaveLoad.TreeType.Pine):
    47.                     treeType = pineTree;
    48.                     break;
    49.                 case (TreeSaveLoad.TreeType.Oak):
    50.                     treeType = oakTree;
    51.                     break;
    52.                 case (TreeSaveLoad.TreeType.Maple):
    53.                     treeType = mapleTree;
    54.                     break;
    55.                 default:
    56.                     Debug.LogError("Missing tree type.");
    57.                     break;
    58.             }
    59.             var treeChild = Instantiate(treeType, tree.position, Quaternion.identity) as Transform;
    60.             treeChild.SetParent(treeParent.transform, true);
    61.             yield return null;
    62.         }
    63.  
    64.         // Call load event
    65.         if (EventManager.Instance.e_loadGame != null)
    66.         {
    67.             EventManager.Instance.e_loadGame.Invoke();
    68.         }
    69.  
    70.         // Call last, after loading is finished
    71.         if (EventManager.Instance.e_loadedGame != null)
    72.         {
    73.             EventManager.Instance.e_loadedGame.Invoke();
    74.         }
    I'm trying to spawn my trees from a save file, as well as call a few Unity events that will handle other loading methods. However, what I'm seeing is that the scene loads AFTER my loading methods are called, resetting the entire scene and throwing a whole bunch of errors. How do I ensure that I can move across scenes and only begin to instantiate objects after the scene has been loaded?
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
  3. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    As per the docs: "When using SceneManager.LoadScene, the loading does not happen immediately, it completes in the next frame. This semi-asynchronous behavior can cause frame stuttering and can be confusing because load does not complete immediately."

    Hook into the sceneLoaded event and call your loading code there.