Creating a Level Select Menu in Unity
When designing anything I like to start by framing myself with a question: “what purpose will this serve?” In this case, the answer is getting the player into a particular level. With that in mind, let's begin.
First Steps.
I like to mentally map out the user flow and sometimes use software to make a map (paper/pen is fine, too). This is great so that I can keep track of where my interface takes the user and what is affected along the way.
I realize that with something as simple as a level select menu our diagram will be very small, but it's still useful in finding the verbs in your UI. The verbs used in the interaction diagram can be gleaned to create a list of primary functions. Note that the two can be created simultaneously.
Process diagrams are a visual way to map out user interactions. They are useful to share within teams so that there is a common understanding of a process.
I also note what information needs to be shown in this menu:
- Level Title
- All acts/scenes in a level (even locked ones)
- Level stats
- The currently selected level
Level stats can be the number of stars a player has earned in a level or in my case it can be the number of objectives the player has completed for the level. Whatever it may be it is important to show the player what they can achieve to poke at the completionist in them.
The same thinking goes for showing all of the possible levels at once. By showing the player what's left, they may be more incline to beat all the levels if there's only x left! You could even put locks over what's to come to imply that those levels must be collected before they can be played.
Grab some paper. A quick paper mockup on paper is great to see how everything fits together without spending too much time on the details.
Quick. Painless. What we're looking for here is overall layout. We will be referencing this when we create our wireframe.
Now let's put together a wireframe in Unity.
I will save you the easy (read: mundane) stuff and will instead touch on ways we can exploit Unity and some organization pointers.
When creating a menu I like parenting everything under an Anchor. This anchor is useful not only in that it keeps all elements in one place, we will also use it to animate the menu later.
We’re going to take advantage of the Grid Layout Group component to neatly arrange our buttons for us. We get this working by nesting all Level buttons under an empty LevelButtons anchor object.
The Grid Layout Group comp will automatically arrange active objects under its parent object.
The CurrentlySelected object will update its position based on what level the player selected last. This will, at a glance, tell players what level the currently shown stats/info applies to.
Now let's add some logic to our basic wireframe.
When coding a menu like this, I want to make it easy on myself as a designer. This means I want as little setup time in Unity’s inspector. My controller will need only two pieces of information to function properly: the level title, and the number of level/acts.
The level title will be used when generating the individual Act buttons so that scenes can be referred to in my project directory. For example, “Windy Valley” will actually be “WindyValley_1” in the function.
The beauty of this script is in the fact that we only need to set the name once and as long as we keep our directory organized (as we should be) then loading levels just works.
Later, we could even create a level manager that populates the LevelSelectController title and number of levels for us!
A couple things happen when a user presses a level: We first check to see if the level was already selected, if it was then we assume that the player's intent was to start the level, otherwise we select the level.
When a level is selected, we have to update the info text. For now I'm using a tempStats array to pull values from but later in development I'll load the numbers from a save file. Each level will have an associated number of objectives completed.
Lastly, when a level is selected the SelectedLevelGraphic must reposition itself to the selected level. It would be weird if we updated the level information at the bottom without telling the player that a different level was selected.
Time for Animation and Polish.
Lastly, I want a nice, quick transition to the act itself. A hard black screen is too jarring and we can do much better using Unity's built-in animator.
I like making state trees within Unity's animator. In this case I'll set up two states for the menu: idle and hidden. The idle state is the default state of the menu; players will interact with the menu in this state. The hidden state moves the menu out of the screen. The flow between these states will be controlled by a variable called "Hide" which I set up in the animator window.
Using animatorComponent.SetBool("Hide", true); will toggle this variable for us.
This is where the Anchor parent object shines. We will only have to animate its position to move the entire menu on or off screen!
I've went ahead and did another art pass on the elements within Photoshop. Here's the final result after some asset swapping.
And that's a wrap. Stay tuned for more quick process rundowns to take a peek at how I work.
Have questions? I might have answers. Reach me via Twitter @BenLapid.
Hope you learned something,
Ben