Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Question How can I check if the scene I want to load is exist?

Discussion in 'Editor & General Support' started by lazy_Ghosst, Feb 7, 2023.

  1. lazy_Ghosst

    lazy_Ghosst

    Joined:
    Feb 12, 2022
    Posts:
    18
    I want the script to make sure the scene The player wants to load exists and if not to direct the player to another scene.
    How can I do it?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    32,430
    I use this snippet to grab all the scene file paths at runtime. From that you can easily check if what you want is there.

    NOTE: pay careful attention to the difference between feeding just the name to load the scene versus what this API returns, which is the full path to each scene:

    Code (csharp):
    1.         List<string> sceneList = new List<string>();
    2.         for (int i = 1; true; i++)
    3.         {
    4.             var s = UnityEngine.SceneManagement.SceneUtility.GetScenePathByBuildIndex(i);
    5.             if (s.Length <= 0)
    6.             {
    7.                 break;
    8.             }
    9.             else
    10.             {
    11.                 sceneList.Add( s);
    12.             }
    13.         }
     
  3. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Another way would be to look for a scene (by name or index), and to simply check whether what's returned is "valid".

    Code (CSharp):
    1. var a = SceneManager.GetSceneByName("MyAwesomeAndTotallyAmazingScene");
    2. return a.IsValid();
     
    Kurt-Dekker likes this.
  4. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    654
    Doesn't that only work for loaded scenes?

    I believe you can only get a Scene struct for scenes that have been loaded. I'm not super confident, though, since the Scene struct has an "isLoaded" field...which seems a bit redundant if you can only get loaded scenes.
     
  5. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Oops, yeah. My bad.
    ByName() will only traverse loaded scenes.
    ByBuildIndex() will traverse all in the build-settings.

    It's a struct. It will return default(Scene) when it can't find anything (so NOT NULL)
     
  6. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Correcting myself.. Wrong again..

    ByBuildIndex: Unity - Scripting API: SceneManagement.SceneManager.GetSceneByBuildIndex (unity3d.com)
    This method will return a valid Scene if a Scene has been added to the build settings at the given build index AND the Scene is loaded. If it has not been loaded yet the SceneManager cannot return a valid Scene

    Looks like SceneManager will always ONLY handle currently loaded scenes.
    SceneUtility Unity - Scripting API: SceneUtility (unity3d.com) is what you should use in all other instances/conditions.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    32,430
    DOH! You are correct chemical!

    ALL of these return false for .IsValid(), and this scene definitely exists, but is not loaded:

    Code (csharp):
    1.         scene = SceneManager.GetSceneByName("Assets/0zeroscene/zeroscene");
    2.         scene = SceneManager.GetSceneByName("0zeroscene/zeroscene");
    3.         scene = SceneManager.GetSceneByName("zeroscene");
    Once
    zeroscene
    is loaded, the only form of naming that works for the above API is the simplest:

    Code (csharp):
    1.         scene = SceneManager.GetSceneByName("zeroscene");
    All the other path variations (including
    0zeroscene/zeroscene
    ) don't work. This latter one surprises me because for SceneManager.LoadScene(), the path above works just fine.
     
  8. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780

    SceneManager-Description:
    Scene management at run-time.

    SceneUtility-Description:
    Scene and Build Settings related utilities.

    I guess they take the 'management'-part quite literally..
    SceneManager is just there to manage/maintain the currently active scenes.
    SceneManager.LoadScene() will probably use SceneUtility somewhere to see if the scene you want to load actually exists.
     
    chemicalcrux likes this.
  9. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    654
    Yeah, it's not terribly intuitive. I was surprised by this the first time it came up...

    Anyway, I would use SceneUtility.GetScenePathByBuildIndex to build a list of valid scene paths. If the player is typing in a scene name, you could test if any of those paths contain the name they entered.

    Although, that sounds a bit weird -- I'd rather just let the player choose from a list of scenes known to exist...unless you're doing something weird with runtime Scene generation, I guess.
     
  10. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    1,397
    I am trying to figure out what @lazy_Ghosst is trying to do. Players really have no business knowing the names of scene assets. The game should know them. The way the game knows them isn't by name, like the editor knows them. Tons and tons of data get thrown out in the build process to make sure it's slim and limited to what you actually intended to build. The game should only know scenes by the index in the build, or by an Addressable reference. The game could load a scene by name, but those are also checked one-by-one with the scene indices, the game doesn't scan scene names to remember them. If you want to present a list of names to the player, or let the player type a string, that's up to you to build using game code.
     
  11. lazy_Ghosst

    lazy_Ghosst

    Joined:
    Feb 12, 2022
    Posts:
    18

    I made a game containing several levels, and although I already set the level buttons I haven't built the scenes themselves. But because I wanted to let people play the game I wanted that if the player pressed the level button for a level that doesn't exist yet (because I didn't make it yet) it would send him back to the main menu.
     
  12. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    654
    Oh, that sounds a lot more straightforward.

    tbh, I would just try to load the scene, then check if the button still exists a second later. If it does, the scene didn't load, so you can go ahead and load the default scene.

    Alternatively, you could use this add-on. It lets you make a field that stores a Scene reference. That's what I do for one of my games.

    Then, just check if something is assigned. If not, load the default scene.