You may have noticed that MadLevelTester scene has been used in earlier examples multiple times. That is because this is the easiest way to test your newly created level select screen and level configuration. It is also a scene in which you can look into to get to know how Mad Level Manager API actually works. This documentation page will explain in detail how the MadLevelTester scene is constructed.

Introduction

First you need to find the MadLevelTester scene. It’s located in Mad Level Manager / Examples / Scenes / MadLevelTester:

In Game View it looks like this:

All graphics (fonts, sprites) are created using Mad Level Manager UI tools (located in Tools → Mad Level Manager → Create UI menu). The Hierarchy of this scene looks like this:

You can see that:

  • All graphics are located under Panel object. This is a requirement for all UI objects of Mad Level Manager.
  • There are 4 circle objects with stars objects within.
  • There is the manager object to hold the manager script.

There are also two scripts attached to these objects:

  • MadLevelTesterController.cs script that is attached to the manager object.
  • MadLevelTesterOption.cs script that is attached to all four circle objects.

MadLevelTesterController Script

This one is attached to the manager game object which in the inspector looks like this:

As you can see there’s some objects attached here – it will be explained in a moment. Let’s look at the top of this script:

public class MadLevelTesterController : MonoBehaviour {
    
    public MadText levelNameText;
    public MadText argumentsText;
    public MadText backToMenu;
    public MadText levelCompletedText;
    public MadText levelNotCompletedText;
    public MadSprite[] other;

There are some public fields which reveal themselves in the inspector as seen above. The controller script needs reference to all sprites because it will eventually hide them when the “level completed” animation is played. Some of them need to be modified by the controller in a specific way. That’s because we have the distinction between texts and “other” sprites.

Controller Initialization

Start() code looks as follows:

 1     void Start() {
 2         levelNameText.text = "Level Name: '" + MadLevel.currentLevelName + "'";
 3         
 4         if (!string.IsNullOrEmpty(MadLevel.arguments)) {
 5             argumentsText.text = "Arguments: " + MadLevel.arguments;
 6         }
 7         
 8         backToMenu.onMouseDown = backToMenu.onTap = (sprite) => {
 9             MadLevel.LoadLevelByName("Level Select");
10         };
11     }

Now you can see why we needed distinction between text and other sprites:

  • Line 2 is setting level name using MadLevel.currentLevelName so it always displays current level name.
  • Line 4 is checking for existence of arguments for the current level.
  • Line 5 is setting these arguments to argumentsText to be displayed on screen.
  • Line 8 is connecting onMouseDown and onTap events of backToMenu label, and it’s making it to return to “Level Select” level on the line 9.

This is all that you need to know about the controller.

There’s also method called PlayFinishAnimation(), but it’s only responsible for fancy animations, so it won’t be explained here.

MadLevelTesterOption Script

MadLevelTesterOption script is attached to all four icons on the scene. It waits for click and tap events, and reacts to them as it should.

In Mad Level Manager 1.3.1 there is a typo in this script name. It’s called MedLevelTesterOption (Med instead of Mad). In newer versions this error is corrected.

Here it is shown what it looks like in the circle_100 inspector:

There are 4 circles to distinct 4 different outcomes:

  1. Will earn 50 points, won’t earn a star, won’t complete the level.
  2. Will earn 100 points, one star, and complete the level.
  3. Will earn 150 points, two stars, and complete the level.
  4. Will earn 200 points, three stars, and complete the level.

Because we’re focusing on star_100, it should earn us 100 points and complete the level. What’s more, completing the level should take us to the next one, but failing will take us back to the level select screen.

Option Fields

Let’s look at the top of the MadLevelTesterOption script:

public class MedLevelTesterOption : MonoBehaviour {

    public int points; // number of points that this option gives
    bool completed = false;

To distinct number of points for each circle, you can notice public points field. There are also two helper fields: sprite and completed. These will be explained in a moment.

Option Initialization

 1     void Start() {
 2         var sprite = GetComponent<MadSprite>();
 3 
 4         // connect to sprite onMouseDown && onTap event
 5         sprite.onMouseUp = sprite.onTap = (s) => {
 6         
 7             // star_1, star_2 and start_3 properties are names or game objects
 8             // that are nested under every icon in the level select screen
 9             
10             // note that if you've gained 3 stars already there's no possibility to lost them
11         
12             // first star gained when points number is at least 100
13             if (points >= 100) {
14                 EarnStar("star_1");
15                 MarkLevelCompleted();
16             }
17             
18             // second star gained when points number is at least 150
19             if (points >= 150) {
20                 EarnStar("star_2");
21                 MarkLevelCompleted();
22             }
23             
24             // third star gained when points number is at least 200
25             if (points >= 200) {
26                 EarnStar("star_3");
27                 MarkLevelCompleted();
28             }
29             
30             // play animation
31             var controller = GameObject.FindGameObjectWithTag("GameController");
32             var script = controller.GetComponent<MadLevelTesterController>();
33             script.PlayFinishAnimation(sprite, completed);
34             
35             StartCoroutine(WaitForAnimation());
36         };
37     }

This also requires some explanation:

  • Line 2 gets attached MadSprite component to connect it to onMouseUp and onTap events on line 5
  • Line 13 checks if the number of points is equal or greater than 100, if so EarnStar() method is called, then MarkLevelCompleted(). These two are explained below.
  • Notice that on lines 19 and 25 similar things happen. There’s no else clause because 150 points will earn the first and the second star, and 200 points should earn all three. Marking level completed two or three times won’t break anything in this scenario. Notice that earning 50 points wouldn’t earn any star nor complete the level.
  • Starting from line 31, end level animation is played.
  • On line 35 WaitForAnimation() is called, and this will be explained in a moment.

EarnStar()

This one is very simple:

    void EarnStar(string name) {
        // set level boolean sets level property of type boolean
        MadLevelProfile.SetLevelBoolean(MadLevel.currentLevelName, name, true);
    }

To set level properties like stars, you must call one of the SetLevelSomething() methods of MadLevelProfile. It works just as PlayerPrefs, but it allows you to set more specific types and level properties, like completed or locked. In this case boolean property is set. First parameter requires the level name we want to set this property for, so we’re providing current level name. The second one needs the parameter name, third parameter value to set. This method is called EarnStar() so the value should be always true.

MarkLevelCompleted()

This one is simple too:

    void MarkLevelCompleted() {
        // sets the level completed
        // by default next level will be unlocked
        MadLevelProfile.SetCompleted(MadLevel.currentLevelName, true);
        
        // manual unlocking looks like this:
        // MadLevelProfile.SetLocked("level_name", false);
        
        // remembering that level is completed
        completed = true;
    }

Most important call here is SetCompleted(). As explained before, it sets completed flag for the level, which usually unlocks next level in the order. Also we set completed field to true because we will need this information later in the code.

WaitForAnimation()

The only reason why this is started in coroutine is that there’s animation played in the background that we must wait for.

 1     IEnumerator WaitForAnimation() {
 2         yield return new WaitForSeconds(2.2f); // animation lasts 2 second
 3         
 4         if (completed) {
 5             // if level is completed go to next level or to 'Level Select'
 6             // depends of it this the last level
 7             if (MadLevel.HasNext(MadLevel.Type.Level)) {
 8                 MadLevel.LoadNext(MadLevel.Type.Level);
 9             } else {
10                 MadLevel.LoadLevelByName("Level Select");
11             }
12         } else {
13             // if not completed go back to the menu
14             MadLevel.LoadLevelByName("Level Select");
15         }
16     }

If you’re not planning to delay jump to the next level, don’t think too much about the first and the second line.

  • On line 4 we’re checking if the level is completed (field set before).
    • If completed, then on line 7 we’re making sure if there’s next level of type Level. Setting correct level type is important to distinguish playable levels from the Other or Extra levels.
      • If there is next level of type Level, then load it on line 8.
      • If there’s no next level, then it’s time to get back to level select screen on line 10. It’s loaded by its name.
    • If this level is not completed, we’re also going back to level select screen on line 14.

Summary

And that’s it! If you’re looking for more resources, you may want to read about Workflow API and Save & Load API.