I'm making my first 2D topdown shooter game. I'm working on the loading part of the game. I have this functioning loading screen function (a method of my GameManager class) I made. I tried swapping between the main title scene and the first level a few times to test it. After loading the first level, then the title screen, when I try loading the first level back again the load screen is stuck. The whole thing is working on a coroutine, and after some debugging I figured out the problem was that this coroutine stopped executing in a certain part of the code for some reason.
public static bool isLoadingScene { get; private set; } = false;
public void LoadScene(int sceneIndex)
{
// If another scene is already loading, abort
if (isLoadingScene)
{
Debug.LogWarning($"Attempting to load scene {sceneIndex} while another scene is already loading, aborting");
return;
}
isLoadingScene = true;
var sceneLoader = FindObjectOfType<SceneLoader>().gameObject;
if (sceneLoader != null)
{
// Make the loading screen appear
var animator = sceneLoader.GetComponent<Animator>();
animator.SetTrigger("appear");
// Make sure the SceneLoader object is maintained until the next scene
// in order to not make the animation stop
DontDestroyOnLoad(sceneLoader);
}
else // If a SceneLoader is not found in the current scene, throw an error
{
Debug.LogError($"SceneLoader could not be found in {SceneManager.GetActiveScene().name}");
}
// Unload active scene and load new one
StartCoroutine(LoadScene_(sceneIndex, sceneLoader));
}
IEnumerator LoadScene_(int sceneIndex, GameObject sceneLoader)
{
float t = Time.time;
// Start loading the new scene, but don't activate it yet
AsyncOperation load = SceneManager.LoadSceneAsync(sceneIndex, LoadSceneMode.Additive);
load.allowSceneActivation = false;
// Wait until the loading is finished, but also give the loading screen enough
// time to appear
while (load.progress < 0.9f || Time.time <= (t LoadingScreen_appearTime))
{
yield return null;
}
// Activate loaded scene
load.allowSceneActivation = true;
// Unload old scene
AsyncOperation unload = SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene());
// Wait until it's finished unloading
while (!unload.isDone) yield return null;
// --- THE COROUTINE STOPS HERE DURING THE 3RD LOADING --- //
// Make the loading screen disappear
sceneLoader.GetComponent<Animator>().SetTrigger("disappear");
// Wait until the disappearing animation is over, then destroy the SceneLoader object
// which I set to DontDestroyOnLoad before
yield return new WaitForSeconds(LoadingScreen_disappearTime);
Destroy(sceneLoader);
isLoadingScene = false;
}
Only during the 3rd loading, right after the while (!unload.isDone) yield return null; line the coroutine just stops executing (I know it because I inserted a Debug.Log inside the while loop and it got called, but I inserted one right after and it did NOT get called).
Any suggestions?
CodePudding user response:
I figured out the problem by myself. The GameManager itself was programmed as a singleton, and since there was a GameManager in both scenes that was messing things up. Had to move the GameManager to a separate scene loaded additively.