unity coroutine 无故停止
Posted
技术标签:
【中文标题】unity coroutine 无故停止【英文标题】:Unity coroutine stopping for no reason 【发布时间】:2021-11-25 04:53:22 【问题描述】:我正在制作我的第一个 2D 自上而下的射击游戏。我正在处理游戏的加载部分。我有这个功能加载屏幕功能(我的 GameManager 类的方法)我做了。我尝试在主标题场景和第一关之间切换几次来测试它。加载第一级后,然后是标题屏幕,当我尝试再次加载第一级时,加载屏幕卡住了。 整个事情是在一个协程上工作,经过一些调试,我发现问题是这个协程由于某种原因在代码的某个部分停止执行。
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 并且它被调用了,但是我在之后插入了一个并且它没有被调用)。
有什么建议吗?
【问题讨论】:
你可能在协程完成之前加载了一个新场景。 这怎么可能?我在 LoadScene() 的开头放置了一个 if 检查,以避免同时存在两个加载进程。 您是否尝试过生成新的 WaitForEndOfFrame() 而不是 null? 不。我应该把它放在两个产量中的哪一个?为什么? 【参考方案1】:我自己解决了这个问题。 GameManager 本身被编程为单例,因为在两个场景中都有一个 GameManager 把事情搞砸了。必须将 GameManager 移动到附加加载的单独场景。
【讨论】:
以上是关于unity coroutine 无故停止的主要内容,如果未能解决你的问题,请参考以下文章
Unity C# - 在完成之前停止执行IJobParallelFor