Questions about SceneManager and SceneManagement

Hey Folks,

I have some questions and if some of you fellow devs can answer them great but it would really really great if someone from Unity could jump in too give some more in-depth information.

Afaik the “new” SceneManagement/SceneManager renders the old Level-Management obsolet which you also can see when you do some coding and the API tells you so :wink:

But how exactly can I get specific scenes I’d like to load? Either I’m not understanding it, the docs are not well documented on this matter (as is often the case, sadly ) or it just is not possible.

Scenario A)

I want to check if a specific scene exists in my build.

 // **************************************************************************
        #region Inspector Variables

        public string sceneToLoad;
        public LoadSceneMode loadSceneMode;

        #endregion

    
        [UsedImplicitly]
        void Start()
        {
            if (!SceneManager.GetSceneByName(sceneToLoad).IsValid())
            {
                Debug.Log.Info("SceneToLoad wont be able to load since it is not in the buildsettings or is not valid");
            }

        }

When this script is attached to a gameobject in my scene, I’ll get the log right away when the scene starts ALTHOUGH the scene named by the string sceneToLoad does exist and is in the Buildsettings.
Now I was a bit confused. I understand that .GetSceneByName returns a sceneObject and not a bool, that’s why I used the .IsValid-Function to check if the returned scene is in somewhat form valid.
Since the log was printed it seems the scene wasn’t valid. That was the point I looked in the docs.

First of all: this way of documentation is terrible, since it is lacking information. You can’t state ONE example when something IsValid or not. What are other examples? List ALL of them, please.

Now after reading this I was as clueless as before. Then I looked at the .GetSceneByName-Method:

And I think I got it then. The SceneManager works differently than I thought. I knew that we can work with multiple scenes now in the Editor, but I didn’t realize that this makes actually a difference when checking for scenes. The Scene I want to check HAS to be added to the SceneManager first - meaning when speaking in Edit-Time the scene I want to check has to be added in the Hierarchy and only then .IsValid() can be true.

Now for the question: I looked at all methods of the SceneManager and apparently none gave me the possibility to check if a scene actually exists in my game/buildsettings. How can I check for that?

Scenario B) (which correlates with Scenario A)

This method here: SceneManager.CreateScene()

This method is dedicated to use at runtime, for EditScripting another method is suggested in the docs.
Now this method would be a case where I’d like to check if the created scene actually exists. How does the method work? Is the created scene added to the sceneCountInBuildSettings? Unlikely, since we’re at runtime.
Is it added to the sceneCount? Probably not.

In our game only one scene is loaded/active at a time so the sceneCount would ALWAYS be 1 in our case.

Like if I would use this method for some kind of procedural generated game (just assume we would like to use it, not if it’s good or bad practice)

  • SceneManager.CreateScene() creates a scene and I add stuff to it.
  • Player plays game, game saves at specific points.
  • Player shuts off game
  • Player starts game and wants to load that scene

→ how do I check for that specific scene?

I mean I know I could write everything manually, which is “no problem” per se - but is there actually a way within Unity to check for the existence of scenes?

Cheers

1 Like

Hey!

Scenario A):

As far as I understood it, the SceneManager refers to the “loaded” scenes (at least in the editor a scene can be added but unloaded, therefore the quotes). The scenes in the BuildSettings are NOT automatically added to the SceneManager. I don’t know how to check for a scene name in the build settings, but a workaround could be iterating over the list of scenes in the BuildSettings (SceneManager.GetSceneByBuildIndex) and checking for the name. Take a look at the difference in the documentation for GetSceneByBuildIndex and GetSceneAt.

Also be aware that there are to different SceneManagement namespaces:
There is
using UnityEngine.SceneManagement;
and
using UnityEditor.SceneManagement;

Scenario B):
Scenes you create at runtime are just dynamically generated objects like every GameObject or component or custom object and won’t be saved in any way. If your level is procedurally generated, you should be able to recreate it with a seed or similar - but saving the changes the player made is up to you. Sorry if I misunderstood your question here. :slight_smile:

Cheers,
Jan

2 Likes

Hey @DerWoDaSo , thanks for the reply :slight_smile:

Yes, this is how I understand the SceneManager, too. As for manually iterating through the names: yeah, it seems that is the only possible way right now - at least in 5.5 - .GetSceneByBuildIndex is not available in 5.4.

For Scenario B)

Ah yes, I didn’t know Unity would treat the scenes just as “objects”, thought maybe these would be added in an internal SceneContainer or something like that.

Use:

SceneUtility.GetBuildIndexByScenePath(SceneName);

From: Unity - Scripting API: SceneManagement.SceneUtility.GetBuildIndexByScenePath

And check if the returned int is greather than zero. I believe this class is available from 5.5 and on. You don’t need the path. With the scene name just works.

Example:

//In your class declaration
private static string AboutSceneName = "Scenes/About Scene";
//...
//In your method
            var aboutSceneIndex = SceneUtility.GetBuildIndexByScenePath(AboutSceneName);
          
            if (aboutSceneIndex >= 0)
                SceneManager.LoadScene(AboutSceneName);
            else
                Debug.Log("Error loading the About scene. Have you added it to the build in \"Build Settings\"?");

I agree with you that the documentation is lacking, and all of this feels half backed.

Cheers!

1 Like