Design question for arcade levels

(Think “Asteroids”…)

I’d like to know if it’s OK to use a design where a GameManager script is spawning player & enemies, announcing level numbers etc, all from within Update.

The idea if just to use something like this:

    void Update()
    {
        while(!gameover)
        {
            // Do I need to draw a new level? -> announce level #, pause, spawn new level
            // Has the player lost 3 lives? -> gameover = true
        }
}

This seems logical to me from a functional point of view, but it does seems weird to have the GameManager check if the game was over on every single frame.

Wondering if there was a “proper” way to do it.

Thanks.

Here’s the current (working) game loop in side the GameManager:

   void Awake()
    {
        // Get reference to the UI Manager script
        UIManager = gameObject.GetComponent<UIManager>();

        // Spawn player
        player = Instantiate(player, Vector2.zero, Quaternion.identity);
        player.isAlive = false;

        audioSource = GetComponent<AudioSource>();
    }



    void Start()
    {
        // Spawn starting asteroids
        for (int i = 0; i < startingAsteroids; i++)
        {
            Instantiate(pfAsteroid, Vector2.zero, Quaternion.identity);
        }

        player.isAlive = true;

        UIManager.UpdateScore(playerScore);
        UIManager.UpdateLives(playerLives);
    }



    void Update()
    {
        if (!player.isAlive && (Time.time - playerDiedTime > 3) && !gameover)
        {
            player.Respawn();
        }

        if (gameover)
        {
            UIManager.DisplayGameOver();
            Invoke("DisplayMenu", 4.0f);
        }

        if (AsteroidController.countAsteroids == 0) {
            Debug.Log("Level Done");
        }
    }

Answering my own question here, thanks to comments and help by @Kishotta. In case someone searches for a similar answer, here’s what I can up with (and I’m not even using Update in the GameManager class, there’s no need for it at all). I’m pretty happy with it.

The part switching the levels in the GameManager displays the level number and waits for 3 seconds using the Invoke command.

    void Start()
    {
        // Reset the (static) count variable
        AsteroidController.countAsteroids = 0;

        // Play background music
        audioSource.Play();

        UIManager.UpdateLives(player.lives);
        NextLevel();
    }



    public void NextLevel()
    {
        // Increase level number, display it for three seconds,
        // disable (hide) the player while doing do
        level += 1;
        UIManager.Announce(string.Format("LEVEL {0}", level));
        player.gameObject.SetActive(false);
        Invoke("SpawnAsteroids", 3.0f);
    }



    void SpawnAsteroids()
    {
        // Clear the level message
        UIManager.Announce("");

        // Spawn asteroids based on level number
        for (int i = 0; i < startingAsteroids + level - 1; i++)
        {
            Instantiate(pfAsteroid, Vector2.zero, Quaternion.identity);
        }

        // Reset player to center and enable (unhide) it
        player.gameObject.transform.position = Vector2.zero;
        player.gameObject.SetActive(true);
    }

The AsteroidController class checks for a static variable that counts the spawned asteroids and, when there are none, called the NextLevel method on the GameManager:

    public void Break()
    {
        if (phase < 2)
        {
            SpawnAsteroid(phase + 1);
            SpawnAsteroid(phase + 1);
        }
        gameManager.ScorePoints((phase + 1) * 2);
        countAsteroids -= 1;
        audioSource.pitch = Random.Range(0.8f, 1.2f);
        audioSource.Play();
        sr.enabled = false;
        col.enabled = false;
        if (countAsteroids == 0)
        {
            gameManager.NextLevel();
        }
        Destroy(gameObject, 4.0f);
    }

In this way I’m avoiding adding an additional “game loop” entirely. Everything is handled by method calls when appropriate.

It looks like you’re trying to create a custom game loop INSIDE unity’s game loop. Update() get’s called once per frame, with the expectation that the code within that function is completed before the scene cameras render that frame. Your player is very unlikely to lose all 3 of their lives in a single frame meaning your game will be stuck in an infinite loop on frame 1.

Did you mean to use an if statement instead of a while loop?