How to upgrade from Application.loadlevelasync to scenemanagment? C#
private int loadLevel = 1;
AsyncOperation async = Application.LoadLevelAsync(loadLevel);
This is what I've used to change level but now its depricated and Im upgrading to Scenemanagment.
SceneManager.LoadSceneAsync(loadLevel, LoadSceneMode.Single);
(Build settings have 4 scenes active) Nothing is working using the Scenemanagers way of switching scenes since Unity always freeze once this code is started. Ends up with "Unity is not responding" and me forcing it to quit...
EDIT: Turns out I can change level using this BUT only to the current active scene. Not any of the other 3 scenes using their index number from build settings. How come? I would like to get advice on how to proceed and/or how to fix this issue. Thanks!
COMPLETE CODE:
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
public class SceneManager2 : MonoBehaviour {
private int currentLevel;
void Awake()
{
currentLevel = SceneManager.GetActiveScene().buildIndex;
}
//Update function will be running every frame in-game.
void Update()
{
//Check if level changed and apply changes.
if (SceneManager.GetActiveScene().buildIndex != currentLevel)
{
print("level has changed. Fixing.");
currentLevel = SceneManager.GetActiveScene().buildIndex;
}
}
//Function to initiate scene change.
public void ChangeScene(int loadLevel)
{
//start the background load.
StartCoroutine(CallLoad(loadLevel));
}
//Background load function.
IEnumerator CallLoad(int loadLevel)
{
AsyncOperation async = SceneManager.LoadSceneAsync(0); //Application.LoadLevelAsync(loadLevel);
yield return async;
}
}
I have stripped the code some to make it easier for you.
Answer by EmHuynh · Feb 17, 2016 at 02:40 AM
Hello, @xN0ticX.
Based on your comments, I don't think this is the problem. But to be sure, i'll point it out. In IEnumerator CallLoad( int loadLevel )
, you used 0 when calling SceneManager.LoadSceneAsync
. Did you forget to replace the 0 with parameter loadLevel? Here is CallLoad:
IEnumerator CallLoad( int loadLevel )
{
AsyncOperation async = SceneManager.LoadSceneAsync( 0 ); // Is this the problem?
yield return async;
}
If that didn't solve your problem, let's continue to the next possible issue. I made some small changes in the LoadLevel.cs script. Both scripts (LoadLevel.cs & SceneManager2.cs) were tested in a project, there were no issues. Scenes were asynchronously loaded. The result is not caused by the slight changes in LoadLevel.cs. The issue in your project might have been caused by how the scripts were used. In my project, I created 3 different scenes and two prefabs. The names of the prefabs are SceneManagerPrefab and LoadLevelPrefab. Their names are based on the script that is attached to them. The value of changeToLevel
of each scene's LoadLevelPrefab are set in the inspector. After the setup, all scenes were added to the list of scenes in build. Everything worked the way it should.
Here are the hierarchy of the scenes from my project:
Scene1
MainCamera
SceneManagerPrefab
- LoadLevelPrefab
Change to Level: 1
Scene2
MainCamera
SceneManagerPrefab
- LoadLevelPrefab
Change to Level: 2
Scene3
MainCamera
SceneManagerPrefab
- LoadLevelPrefab
Change to Level: 0
Now, I bet we are using the scripts differently. This assumption is based on our results and the script, SceneManager2.cs. To check if the scene has changed, an int flag was declared in the script: private int currentlevel;
. For my case, currentLevel is not needed. Each of the scenes in my project has a SceneManagerPrefab object, which contains the script. So every time they load, currentLevel is always set to the build index of the active scene. This occurs in the Awake() function of the script. Thus, rendering currentLevel useless. But at least, it wasn't a problem. Desired scenes were able to load asynchronously.
Did you declared currentLevel
so it can be accessed from scenes without a game object with the component SceneManager2.cs
?
I made another script based on SceneManger2.cs. I removed everything that has to do with the flag currentLevel
. Like SceneManager2.cs, it works. Here it is:
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
public class MySceneManager : MonoBehaviour
{
public void ChangeScene( int loadLevel ) {
Debug.Log( "Called ChangeScene" );
StartCoroutine( CallLoad( loadLevel ) );
}
IEnumerator CallLoad( int loadLevel ) {
Debug.Log( "Called CallLoad" );
AsyncOperation asyncOp = SceneManager.LoadSceneAsync( loadLevel );
yield return asyncOp;
}
}
The code you pointed out using a static '0' ins$$anonymous$$d of loadLevel
variable was just a debuging test from me before i made the loadLevel.cs
to use a public int variable. Simply to see if I could atleast load my current scene build from the index.
The use of the currentLevel
variable is also quite simple. It will be checking if the scene has changed based on indexing of the build settings. If it has, fix, reset & reload other scripts. (This does not control anything with scene loading)
Reason why some or "all" of the variables are publicly aviable is for my preference to debug etc. They are to be changed to private at a later time.
NOTE This code is heavily stripped of code to make it easier to spot errors for you people helping out. All the code I removed were used to call out to other managers I use in the game.
The way Im doing this is by having (Script)scenemanager2 as (prefab)Scenemanager to get access. loadLevel is simply hosting a cube gameobject in the scene world to act as a trigger whenever I touch it with a player. Sending a int property towards Scenemanager to change level via Scene$$anonymous$$anager.LoadSceneAsync
as loadLevel
.
Wierdly enough I havent gotten this to work yet and will, as you did, create a new project and get to the bottom of this mess.
Problem is that unity is freezing everytime I debug this code. I never see any errors etc since I have to force it to quit.
Thanks @EmHuynh for your help.
I can confirm that, IF i strip down my code it runs just as intended. Something else is messing this up somehow. Further investigation is required.
Thanks for taking your time. I'm setting this as solved and thank all of you who tried to help out!
Thank you for the very informed response, @xN0tiCx. If you need further assistance on resolving this issue, let me know! (:
I have narrowed it down to a specific script and I have found the problem causing this issue. Turns out the scene did change. However, Unity did now show any visual changes but ins$$anonymous$$d "froze".
The issue was that I had a few While loop
searching for specific gameobjects that did not exist in the other scene resulting in unity freezing up on me before the scene was even loaded.
Im confident I can find a solution/workaround for this :) Thanks!
Answer by Zoogyburger · Feb 16, 2016 at 07:00 PM
use this:
SceneManager.LoadSceneAsync(1);
and add this at the top of your code:
using UnityEngine.SceneManagement;
Im already using "UnityEngine.Scene$$anonymous$$anagment".
Still can only run the active scene to load. Active scene is 0 in this case and I cannot load 1 for example. Your solution does not work.
Thanks for a quick answer!
EDIT: Let me update this thread with the complete code.
$$anonymous$$aybe you want to take a look at this
http://docs.unity3d.com/ScriptReference/Scene$$anonymous$$anagement.Scene$$anonymous$$anager.html
I have checked docs for answers too.
There is nothing declairing why I can only change to my current scene.
Scene[] scenes = Scene$$anonymous$$anager.GetAllScenes();
print(scenes.lenth); (prints 1)
Will also only find 1 scene. The current one.
And Im confused and been searching the web for information. Docs, Answers & Forums. Came up empty and then created this Thread.
Thanks again for the answer @Zoogyburger
Answer by Kurdle_4855 · Feb 16, 2016 at 07:51 PM
I have had this problem too, try loading the scene by name
Nope, switching over to string did not help me at all. Still thesame. I could use the name of the current scene to load it. Not any of the other. Shame...
Thanks :)
Quick question: You said you HAD this problem? What whas your fix/workaround?
Still havent found a fix to the issue but Im starting to think that this Scenemanager does not read from the buildsettings scene list but rather a list it has itselt and we have to manually program it to add the others...?
AsyncOperation async = Scene$$anonymous$$anager.LoadSceneAsync(Scene$$anonymous$$anager.GetSceneAt(loadLevel).buildIndex);
By using this code I could run the index int of the scene I was currently playing on but none else, once more. However, this did not cause Unity to crash or freeze. I got an error.
UnityEngine.Scene$$anonymous$$anagement.Scene$$anonymous$$anager.GetSceneAt (Int32 index) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/Scene$$anonymous$$anagerBindings.gen.cs:67)IndexOutOfRangeException: Scene index "1" is out of range.
@xN0tiCx, I am checking out your script. I have a question, when is the function: ChangeScene
called?
Its called via another script:
using UnityEngine;
using System.Collections;
public class LoadLevel : $$anonymous$$onoBehaviour {
public int ChangeLevelTo = 0;
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Player")
{
Debug.Log("Player hit: " + this.gameObject + ".");
GameObject.Find("Scene$$anonymous$$anager").GetComponent<Scene$$anonymous$$anager2>().ChangeScene(ChangeLevelTo);
}
}
}
There should be no errors here. Scripts runs fine with the old "Application.loadAsync" compile.
Thanks for taking ur time to check it out @EmHuynh . Appreciate it!
Your answer
![](https://koobas.hobune.stream/wayback/20220612064453im_/https://answers.unity.com/themes/thub/images/avi.jpg)