Unity Coroutine не работает между сценами - PullRequest
2 голосов
/ 03 апреля 2019

Я вызываю сопрограмму, показанную ниже, которая прикреплена к DontDestroyOnLoad объектам, которые сохраняются в разных сценах.

IEnumerator InitMaxScore()
{
    Debug.Log("will wait for some time");
    yield return new WaitForSeconds(1);
    GameObject[] coins = GameObject.FindGameObjectsWithTag("Coin");
    Debug.Log("coins length == " + coins.Length);
    if (coins.Length > 0)
    {
        maxScoreInitialized = true;
        maxScore = score + coins.Length * 10;
        foreach (GameObject healthPickup in GameObject.FindGameObjectsWithTag("Health"))
        {
            maxScore += healthPickup.GetComponent<Pickups>().pointsForLifePickup;
        }
        Debug.Log("maxScore inti == " + maxScore);
    }
    yield return null;
}

Эта сопрограмма вызывается в событии OnLevelWasLoaded указанного игрового объекта, для которого при пробуждении устанавливается значение DontDestroyOnLoad, как показано ниже.

private void Awake()
{
    int numGameSessions = FindObjectsOfType<GameSession>().Length;
    if (numGameSessions > 1)
    {
        Destroy(gameObject);
    }
    else
    {
        DifficultyManagement.setDifficulty(Difficulty.One); // start the game with diff one always
        DontDestroyOnLoad(this.gameObject);
    }
}

Пока печатается журнал "подождет некоторое время" в сопрограмме, Debug.Log ("coins length ==" + coins.Length) печатается не всегда. Я, конечно, не уничтожаю указанный игровой объект на протяжении всей моей игры, которая могла бы привести к тому, что Coroutine будет вести себя таким образом. Поведение также непоследовательное, иногда оно работает, иногда нет, и мне кажется, почему вы не можете принять решение.

Я долго бился об этом и, казалось, не мог это исправить, любые выводы были бы полезны для снятия моего ментального блока: /

1 Ответ

3 голосов
/ 03 апреля 2019

OnLevelWasLoaded устарело, рассмотрите возможность использования события sceneLoaded:

using UnityEngine.SceneManagement;

private void Awake()
{
    int numGameSessions = FindObjectsOfType<GameSession>().Length;
    if (numGameSessions > 1)
    {
        Destroy(gameObject);
    }
    else
    {
        DifficultyManagement.setDifficulty(Difficulty.One); // start the game with diff one always
        DontDestroyOnLoad(this.gameObject);
        SceneManager.sceneLoaded += (scene, mode) => StartCoroutine(InitMaxScore());
    }
}
...