Adventures In UI Building

Welcome back fellow readers and programmers! This week’s blog is all about UI building and design. I’ll be discussing a game UI that I have been developing for one of my puzzles. So let’s get started….

I’m designing this UI for a puzzle that involves putting in a code to open a safe, normally this would be a pretty simple UI design as a keypad that the player enters the code into. In this case the UI is being designed for a dial style safe combination, which makes the UI a bit harder to design. While designing this UI I went through a couple of iterations getting to my final design. I knew that I wanted to include the dial being animated so that the player felt like they were more involved with the game but not make them have to actually find the number with the dial. This proved quite a challenging compromise.

There are three ways to implement a UI in Unity:

  1. Using interactions with game objects.
  2. Building the UI in the game space with a Canvas object
  3. Building the UI with their UI Toolkit

I chose the third method because it seemed like the best, most player friendly option. It is also consequently the easiest to design with because it’s very similar to web design, using XML for layout and CSS style stylesheets. Their XML controls are able to manipulate game objects within the scene without being part of the scene itself. It can also be enables and disabled at will, with just a reference to the XML document.

So, the first design that I tried to build involved some sideways chevron arrows that sat on either side of the dial object. There would have been a double chevron that rotated the dial all the way around and a single chevron to go number by number. I decided against this design because it required giving the player explicit instructions on how the UI functions. This would’ve broken the players immersion into the game and made the puzzle a little confusing a long to solve.

My second design iteration involved three number displays with four buttons around them that changed the number on the display and when all three numbers were correct, the dial would animate like it was being opened. Two of the buttons had +/- 10 and the other two buttons had +/- 1. This proved to be a very confusing for a player. This one would also have needed explicit instructions and the dial would’ve animated after the all the number were correct.

My third and final iteration is something I saw in a different game that I thought was a great interface for this kind of UI and gives a bit of challenge for the player to figure out how it works, providing a better game and puzzle experience. The way this version works is that there are four number displays with four indicators below them, two rotation arrows on either side of the dial, and a back button so the player can go back and forth to look at the code. When the UI is enables, the left most number’s indicator is lit up to show that that’s the number they are changing. When they tap the left arrow, the first number will start changing and moving the dial at the same time, then if they press the other arrow, the indicator flips to the next number which starts at the previous number’s position and move the dial the other way. This pattern continues as you go down the line until the player finishes entering the final correct number. The arrows will also be able to be held down to move through number quickly.

As far as the backend goes, it’s a bit like JavaScript with JQuery meets Python or Ruby. It’s written in C# like all other Unity scripts so you can create classes/objects for the different UI element and each of the elements can be grabbed by reference using a query syntax after getting a reference to the UI documents rootVisualElement. For my control script, I made a class to encapsulate the display numbers and their indicators with some methods for manipulating them. In the main script that sits on the UI document object, one of those objects is created for each display number and then the buttons’ click events are ‘subscribed’ to methods that manipulate the display objects using their encapsulated methods. As of this writing I am still building the interaction backend.

Well that’s it for this week, keep your eyes peeled for my next post!