Code Framework

LevelManager Class

This page specifies each step in creating starter code framework for the LevelManager. Go to the bottom of this page to get the full Starter Code

Start by adding the following code to the top of the LevelManager Class

Updated 4/15/2020 1:00 pm

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

public class LevelManager : MonoBehaviour {

        ///CODE TO BE ADDED HERE

} //end class

Level-State Enums

The next code we'll add to the LevelManager class is a set of Enums that are used to track which state we are in. We'll create a LevelState variable: curLevel, and it's value will change as the Level changes. This corresponds to a simple Finite State Machine for managing levels.

public enum LevelState
{
    start,
    level1,
    level2,
    level3,
    win,
    lose

}

Declare LevelManager Object Reference Variables

After declaring the LevelState enums, then we'll declare the LevelManager's object reference variables.

   LevelState curLevel; //track current level for FSM

    //levelScore is stored in GameData
    int maxLevelScore; //when to change levels

    //UI game Objects - LevelText, StartGameButton, StartGamePanel
    [SerializeField]
    Button startGameButton;

    [SerializeField]
    CanvasGroup startPanelCg;

    [SerializeField]
    Text levelText;

    //references to custom script components
    [SerializeField]
    Spawner spawner;
    //to start the spawner, change objects that are spawned

Start - Initialize Object References

Add the following code to the Start( ) method.

void Start()
    {
        curLevel = LevelState.start;

        maxLevelScore = 30;  //ADJUST FOR YOUR GAME
        startGameButton.onClick.AddListener(NextLevel);

        levelText.text = "";

        Utility.ShowCG(startPanelCg);  //show StartButton

       ///REGISTER AS A LISTENER TO GameData event: OnPlayerDataUpdate
        GameData.instanceRef.onPlayerDataUpdate.AddListener(CheckLevelEnd);

        PlayerController player = FindObjectOfType<PlayerController>();
        if( player != null)
        {
            player.onPlayerDied.AddListener(ReloadMiniGame);
        }
    }

Check For Level End

Write code for the CheckLevelEnd method, this method will be executed every time the OnPlayerDataUpdate event occurs in GameData.

   /// <summary>
    /// Checks the level end.
    ///   If LevelScore > maxLevelScore, then reset the LevelScore and call the nextLevel( ) method
    ///  to change the level
    /// </summary>
    ///this will be called when the OnPlayerDataUpdate event 
    ///happens in GameData, it is registered as a listener for that event

    public void CheckLevelEnd()
    {
        int levelScore = GameData.instanceRef.LevelScore;
        Debug.Log("Check if level is over" + levelScore);

        if (levelScore >= maxLevelScore)
        { ///level has changed

            GameData.instanceRef.LevelScore = 0;   //reset GameData.LevelScore

            NextLevel();  //go to next level
        }

    } //end CheckLevelEnd

NextLevel - Finite State Machine Logic

This method manages the FSM control logic using switch-case structure. Each time this method is called, the matching logic must change the value of curLevel, and call a custom method: loadLevelX( ) where the details of the level loading logic are specified.

 //FSM LOGIC 
    //Every time NextLevel is executed, we KNOW that it is time to change the level
    public void NextLevel()
    {

        switch (curLevel)
        {

            case LevelState.start:  // called when StartPanel, StartGameButton is clicked
                curLevel = LevelState.level1; //change level
                LoadLevel1();
                break;

            case LevelState.level1:  //called when in Level1 from checkLevelEnd( ) 
                curLevel = LevelState.level2; //change level

                LoadLevel2();
                break;
            case LevelState.level2: //called when in Level2 from checkLevelEnd( ) 
                curLevel = LevelState.level3; //change level

                LoadLevel3();
                break;
            case LevelState.level3: //called when in Level3 from checkLevelEnd( ) 
                //ADD logic to determine if it's a winning or losing ending

                MiniGameOver();
                break;

            default:
                Debug.Log("No match on curLevel");
                break;
        }
    } //end NextLevel

LoadLevel Methods

For each level change, a method: loadLevelX( )contains the level change logic. You'll need to add additional LoadLevel Methods for loadLevel3( ), etc.

//These will need to be updated with your code
    void LoadLevel1()
    {
        //STARTS Gameplay, Spawner, etc

        Utility.HideCG(startPanelCg); //hide the StartGamePanel and StartGameButton
        spawner.activeSpawning = true;
        spawner.StartSpawning();
        levelText.text = "Level 1";
        Debug.Log("LoadLevel1");
    }

    void LoadLevel2()
    {
        ///change background image?
        ///change objects getting spawned?
       
        levelText.text = "Level 2";
        Debug.Log("LoadLevel2");
    }

    void LoadLevel3()
    {
        ///change background image?
        ///change objects getting spawned?

        levelText.text = "Level 3";

    }

    void MiniGameOver()
    {


    }

Full Starter Code: Updated 4/15/2020

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;

public class LevelManager : MonoBehaviour
{
    public enum LevelState
    {
        start,
        level1,
        level2,
        level3,
        win,
        lose

    }

    LevelState curLevel; //track current level for FSM

    //levelScore is stored in GameData
    int maxLevelScore; //when to change levels

    //UI game Objects - LevelText, StartGameButton, StartGamePanel
    [SerializeField]
    Button startGameButton;

    [SerializeField]
    CanvasGroup startPanelCg;

    [SerializeField]
    Text levelText;

    //references to custom script components
    [SerializeField]
    Spawner spawner;
    //to start the spawner, change objects that are spawned

    void Start()
    {
        curLevel = LevelState.start;

        maxLevelScore = 30;  //ADJUST FOR YOUR GAME
        startGameButton.onClick.AddListener(NextLevel);

        levelText.text = "";

        Utility.ShowCG(startPanelCg);  //show StartButton

       ///REGISTER AS A LISTENER TO GameData event: OnPlayerDataUpdate
        GameData.instanceRef.onPlayerDataUpdate.AddListener(CheckLevelEnd);

       
    }

    /// <summary>
    /// Checks the level end.
    ///   If LevelScore > maxLevelScore, then reset the LevelScore and call the nextLevel( ) method
    ///  to change the level
    /// </summary>
    ///this will be called when the OnPlayerDataUpdate event 
    ///happens in GameData, it is registered as a listener for that event

    public void CheckLevelEnd()
    {
        int levelScore = GameData.instanceRef.LevelScore;
        Debug.Log("Check if level is over" + levelScore);

        if (levelScore >= maxLevelScore)
        { ///level has changed

            GameData.instanceRef.LevelScore = 0;   //reset GameData.LevelScore

            NextLevel();  //go to next level
        }

    } //end CheckLevelEnd


    //FSM LOGIC 
    //Every time NextLevel is executed, we KNOW that it is time to change the level
    public void NextLevel()
    {

        switch (curLevel)
        {

            case LevelState.start:  // called when StartPanel, StartGameButton is clicked
                curLevel = LevelState.level1; //change level
                StartLevel1();
                break;

            case LevelState.level1:  //called when in Level1 from checkLevelEnd( ) 
                curLevel = LevelState.level2; //change level

                LoadLevel2();
                break;
            case LevelState.level2: //called when in Level2 from checkLevelEnd( ) 
                curLevel = LevelState.level3; //change level

                LoadLevel3();
                break;
            case LevelState.level3: //called when in Level3 from checkLevelEnd( ) 
                //ADD logic to determine if it's a winning or losing ending

                MiniGameOver();
                break;

            default:
                Debug.Log("No match on curLevel");
                break;
        }
    } //end NextLevel


    void StartLevel1()
    {
        //STARTS Gameplay, Spawner, etc

        Utility.HideCG(startPanelCg); //hide the StartGamePanel and StartGameButton
        spawner.activeSpawning = true;
        spawner.StartSpawning();
        levelText.text = "Level 1";
        Debug.Log("LoadLevel1");
    }

    void LoadLevel2()
    {
        ///change background image?
        ///change objects getting spawned?
       
        levelText.text = "Level 2";
        Debug.Log("LoadLevel2");
    }

    void LoadLevel3()
    {
        ///change background image?
        ///change objects getting spawned?

        levelText.text = "Level 3";

    }

    void MiniGameOver()
    {


    }


    public void ReloadMiniGame()
    {
        Utility.ShowCG(startPanelCg); //show start button
        GameData.instanceRef.ResetMiniGameData();
    }


} //end LevelManager

Last updated