unity-game-engineienumerableienumerator

Why yield return null can't executed in Start() void


This problem is not always occurred.But when it happened,I can't find a way to fix it. Here is the code:

    void Start()
    {
        StartCoroutine(test());
    }

    IEnumerator test()
    {
        LoadingBar.maxValue = 1.0f;
        //This is the original code.
        //foreach (var v in Loader)
        //{
        //    Debug.Log(v.Key);
        //    yield return v.Value.Loading();
        //    LoadingBar.value = TotalLoadingProgress;
        //}
        //This is the simplified code.
        for (int i = 0; i < 9; i++)
        {
            Debug.Log("a");//This will show
            yield return null;
            Debug.Log("b");//This will not
        }

        OnLoadingCompleted?.Invoke();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Return))
            StartCoroutine(test());
    }

There is a "yield return null" in every manager's Loading() method.Sometimes it work as i expect,all 9 manager can successfully loaded.But sometimes it's just stuck at "yield return null".

I simplified the code like above.When this test coroutine get started in Start() void,it will only debug one single message:"a" But when this coroutine get started in Update(),all 9 "a" and "b" will showing up as expect.

I have no idea why this code is normal in update but get abnormal sometimes in start void.


Solution

  • learn from my lessons! I writed code like this to switch the UI:

    private void SwitchUI()
    {
        LoadingMenu.gameObject.SetActive(false);
        MainMenuUI.gameObject.SetActive(false);
        BattleUI.gameObject.SetActive(false);
        switch (SceneController.Instance.CurrentMap)
        {
            case "LoaderScene":
                LoadingMenu.gameObject.SetActive(true);
                break;
            case "MainMenu":
                MainMenuUI.gameObject.SetActive(true);
                break;
            default:
                BattleUI.gameObject.SetActive(true);
                break;
        }
    }
    

    And this code caused my problem.The instant SetActive false and setback to true will still break the coroutine.I have to deactive all object at first in editor mode,after that i can enter play mode.