4

Essentially, after testing a few level prototypes, I've decided to stick with my current game idea so I started creating a GameManager to control the flow of levels, etc. I don't have any additional libraries or asset packages being used outside of the default, but for some reason the buildIndex of all of my scenes is -1, which I learned according to the API, means that they're supposed to be loaded through an AssetBundle. Now I can't load anything with SceneManager and I'm not sure how to move forward. I did temporarily have the 2d-extras-master folder in the project as I assumed I'd be using it, but removed it after realizing I wouldn't need it. Does anyone know how to reset the buildIndices of my scenes to the values in the Build Settings? Any/All help is greatly appreciated!

Edit: I should also mention, that the latest Scene I added (when I still had the 2d-extras-manager) still retained a normal buildIndex of 0

Edit #2: So I've found that I can access the buildIndices of the other scenes amongst themselves. It's only when I try to access the buildIndices from my MainMenu Scene that things don't work

Edit #3: I've found a fix, but it doesn't necessarily answer the question. I found that I can force the LoadScene function to work if I know what the buildIndex is, but if I search for it via a scene name, it would return -1.

ex.

// where 1 is the buildIndex of Scene "Main" in BuildSettings
// works
SceneManager.LoadScene(1);

// doesn't work
int index = SceneManager.GetSceneByName("Main").buildIndex; //returns -1
SceneManager.LoadScene(index);

// also doesn't work (Where current scene is buildIndex 0)
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);

3 Answers3

1

SceneManager.GetSceneByBuildIndex or SceneManager.GetSceneByName and functions alike work only on loaded scenes. If scene isn't loaded it will return -1. Reason is, you can load scenes additively, so it's possible to have even 5 loaded scenes.

It's true that the api is lacking in many ways.

In your case you are trying to use it right after SceneManager.LoadScene(1);, int index = SceneManager.GetSceneByName("Main").buildIndex; returns -1 most likely because scene will be loaded on the next frame "officially".

You could try to wait 1 frame in coroutine and then do that. But usually you will have scene index or scene name to load/save it and not care about logic after scene has been loaded. You can create a manager which will store all of the loaded scenes where you could look up their build indices if you need them to decide what scene to load next.

Alternatively you can use Addressables package which handles a lot, it's hard to get into but scene loading works way better there in my opinion.

0

In the build menu, accessed by clicking in File on Unity Editor you can organize your scenes and add them to the flow like in this image

I'm not sure of it, but I'm supose when you didn't assigned a Scene to the flow, it get sceneIndex = -1. So load a scene, go to BuildSettings, add it to the build flow, do the same to all of them. I think this way you can solve it.

Marcos Defina
  • 128
  • 13
  • All of the scenes are properly added in Build Settings, but the weird thing is, if I try force a load using the index I know (ex. if Scene1 has index 2 using LoadScene(2) loads), but if I try to get the value of the index by using GetSceneByName("Scene1").buildIndex it returns -1 – Adam Elaoud Mar 31 '19 at 00:36
  • Well, this is really weird. Show the key parts of your code which contains it, maybe I can help. – Marcos Defina Mar 31 '19 at 00:49
  • literally the only code I have is "SceneManager.LoadScene(1);" for the onclick function of my menu's play button (where Scene 1 is level 1 in my buildsettings) – Adam Elaoud Apr 02 '19 at 18:33
0

You can use this method to get buildIndex.

https://docs.unity3d.com/ScriptReference/SceneManagement.SceneUtility.GetBuildIndexByScenePath.html

And after checking the validity of the buildIndex, if the buildIndexis not equal to -1, then the scene exists in the build settings.

public static bool SceneExists(string scenePath)
{
    return SceneUtility.GetBuildIndexByScenePath(scenePath) != -1;
}