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.
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