Unity协程无故停止
Unity coroutine stopping for no reason
我正在制作我的第一个 2D 俯视射击游戏。我正在处理游戏的加载部分。我有这个功能加载屏幕功能(我的 GameManager class 的一种方法)。我尝试在主标题场景和第一关之间交换几次来测试它。加载第一关后,然后是标题屏幕,当我尝试再次加载第一关时,加载屏幕卡住了。
整个事情都是在协程上进行的,经过一些调试我发现问题是这个协程由于某种原因在代码的某个部分停止了执行。
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;
}
仅在第 3 次加载期间,紧接着 while (!unload.isDone) yield return null; line 协程刚刚停止执行(我知道它是因为我在 while 循环中插入了一个 Debug.Log 并且它被调用了,但是我紧接着插入了一个并且它没有被调用)。
有什么建议吗?
我自己解决了这个问题。 GameManager 本身被编程为单例,因为在两个场景中都有一个 GameManager 把事情搞砸了。必须将 GameManager 移动到一个单独的场景,以附加方式加载。
我正在制作我的第一个 2D 俯视射击游戏。我正在处理游戏的加载部分。我有这个功能加载屏幕功能(我的 GameManager class 的一种方法)。我尝试在主标题场景和第一关之间交换几次来测试它。加载第一关后,然后是标题屏幕,当我尝试再次加载第一关时,加载屏幕卡住了。 整个事情都是在协程上进行的,经过一些调试我发现问题是这个协程由于某种原因在代码的某个部分停止了执行。
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;
}
仅在第 3 次加载期间,紧接着 while (!unload.isDone) yield return null; line 协程刚刚停止执行(我知道它是因为我在 while 循环中插入了一个 Debug.Log 并且它被调用了,但是我紧接着插入了一个并且它没有被调用)。
有什么建议吗?
我自己解决了这个问题。 GameManager 本身被编程为单例,因为在两个场景中都有一个 GameManager 把事情搞砸了。必须将 GameManager 移动到一个单独的场景,以附加方式加载。