【问题标题】:Unity coroutine stopping for no reasonunity coroutine 无故停止
【发布时间】: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?
  • 不。我应该把它放在两个产量中的哪一个?为什么?

标签: c# unity3d coroutine


【解决方案1】:

我自己解决了这个问题。 GameManager 本身被编程为单例,因为在两个场景中都有一个 GameManager 把事情搞砸了。必须将 GameManager 移动到附加加载的单独场景。

【讨论】:

    猜你喜欢
    • 2018-08-06
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-24
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多