Search Unity

Question How to load an addtive scene AND make it the active scene?

Discussion in 'Scripting' started by MaximumSpice, May 17, 2022.

  1. MaximumSpice

    MaximumSpice

    Joined:
    Oct 25, 2018
    Posts:
    22
    Hey guys,

    I've spent the last few days trying to get my head around this, first time I've actually done multiple scene loading, so I'm new on this stuff and struggling.

    Let me set the scene, I have a managers scene that will be single loaded after the main menu, that is just kept there while the main game runs.
    Then I simply load in using additive scenes for each level.

    I've currently got a script on my level scenes that controls a button for next level, the idea being, you finish the level, an end level screen comes up (all in the same scene), you can click next level or retry level. Next level should load the next level additively, unload the level scene you just finished, while not affecting the managers scene.

    Then, in my current system, my managers scene becomes the active scene. I need to then make my new level the actual active scene but this is where I've become to encounter a ton of problems.

    How do I tackle this?

    upload_2022-5-17_19-0-56.png

    Below is my current (trash tier) script. I know I can also use .isLoaded type stuff, unsure how to do that though. Anyone able to help?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class EndLevelButtons : MonoBehaviour
    7. {
    8.     public int currentSceneIndex;
    9.     public int maxSceneIndex;
    10.     public int nextLevelIndex;
    11.     public string nextLevelName;
    12.     //public int previousLevelIndex;
    13.     //public string previousLevelName;
    14.  
    15.     private void Start()
    16.     {
    17.         currentSceneIndex = SceneManager.GetActiveScene().buildIndex - 1; // take one number off since we start at zero index
    18.         maxSceneIndex = SceneManager.sceneCountInBuildSettings;
    19.  
    20.         nextLevelIndex = currentSceneIndex + 1;
    21.         nextLevelName = "Level_" + nextLevelIndex;
    22.     }
    23.  
    24.     // these may not work correctly and may need step functions like coorutines to time thme out
    25.  
    26.     public void NextLevel()
    27.     {
    28.         if (currentSceneIndex < maxSceneIndex - 2)
    29.         {
    30.             //SceneManager.UnloadSceneAsync(currentSceneIndex + 1);
    31.             //SceneManager.LoadScene(currentSceneIndex + 2, LoadSceneMode.Additive);
    32.             //SceneManager.SetActiveScene(SceneManager.GetSceneByBuildIndex(currentSceneIndex + 2));
    33.             StartCoroutine(SetActiveScene());
    34.             print("loading next level");
    35.         }
    36.         else
    37.         {
    38.             print("No more levels yet!");
    39.         }
    40.     }
    41.  
    42.     public void RetryLevel()
    43.     {
    44.         SceneManager.UnloadSceneAsync(currentSceneIndex);
    45.         SceneManager.LoadScene(currentSceneIndex, LoadSceneMode.Additive);
    46.         print("Restarting level");
    47.     }
    48.  
    49.     public void QuitToMainMenu()
    50.     {
    51.         SceneManager.LoadScene(0, LoadSceneMode.Single);
    52.         print("Loading Main Menu");
    53.     }
    54.  
    55.     private IEnumerator SetActiveScene()
    56.     {
    57.         SceneManager.LoadScene(currentSceneIndex + 2, LoadSceneMode.Additive);
    58.         yield return new WaitForSeconds(0.01f);
    59.         SceneManager.UnloadSceneAsync(currentSceneIndex + 1);
    60.         SceneManager.SetActiveScene(SceneManager.GetSceneByBuildIndex(currentSceneIndex + 2));
    61.         Time.timeScale = 1;
    62.         yield return new WaitForSeconds(0.01f);
    63.  
    64.  
    65.         //SceneManager.UnloadSceneAsync(currentSceneIndex + 1);
    66.         //SceneManager.LoadScene(currentSceneIndex + 2, LoadSceneMode.Additive);
    67.         //yield return new WaitForFixedUpdate();
    68.         //SceneManager.SetActiveScene(SceneManager.GetSceneByName(nextLevelName));
    69.         //yield return new WaitForFixedUpdate();
    70.     }
    71. }
    72.  
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    MaximumSpice likes this.
  3. MaximumSpice

    MaximumSpice

    Joined:
    Oct 25, 2018
    Posts:
    22

    Right okay, I shall try this tonight and report back!

    Thank you!
     
    Kurt-Dekker likes this.
  4. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    an other way of doing this as well is using LoadSceneAsync, since when you call it it will return a AsyncOperation. With this you can either yield it in a coroutine or subscribe to its Completed event to execute logic once the scene is fully loaded and ready.
     
    MaximumSpice likes this.