#6 Programming the User Interface in Unity

Introduction

In this article we will program the logic of the user interface created in video 5 of the labyrinth series. If you did not read the previous article, in summary we created a user interface in Unity, which will have the minimum functionality for the user to interact with the game.

Go to the project’s Main Page

Before we begin, I invite you to watch the following video.

Objective of this article

In the previous article we designed a simple user interface so that the user can control the fundamental aspects of our game, such as starting the game, knowing how much time he has left, etc…

At this point we are going to use the GameControl Script to manage the user interface. In the following chapters we will delegate this responsibility to a new Script.

To summarize the elements of the user interface we have two screens, one for the main menu which contains only one button that serves to start the game. The second screen is for the game and has a text element that will show the amount of time left to finish the game.

Resolution

In the GameControl Script we define three serialized GameObjects, one for the camera that is active in the main menu, another for the menu interface and another for the game interface.

The three GameObjects defined are highlighted in Figure 1.

Fig. 1: Three serialized GameObjects are defined for the camera and interface displays.

In figure 2 we can see that these new fields appear in the inspector.

Fig. 2: The three GameObjects appear in the inspector.

We take the objects created in the previous video and drag them to the fields in the inspector. These objects are the camera, the GameObject MainMenu and the GameObject Game.

Fig. 3: We take the GameObjects from the hierarchy and take them to the inspector.

Fig. 4: In the inspector we place each GameObject in its corresponding space.

StartGame and EndGame methods

We are going to define two methods, one is going to be called “startGame” and the other “endGame”. The startGame method will have the function of doing everything necessary for the game to start, i.e. setting the timer to zero, placing the character’s prefab, placing the pedestal in a random position on the stage and so on. Keep in mind that these actions will probably be defined in other methods.

In the endGame method we remove all objects from the scenario, go to the main menu and so on.

Fig. 5: The startGame and endGame methods are defined.

In the methods we are going to activate and deactivate the corresponding elements, as can be seen in figure 6.

Fig. 6: Inside each method we place the appropriate instructions.

Let’s go to the hierarchy and select the “Start” button, to observe its properties in the inspector.

Fig. 7: The start button in the hierarchy is selected.

Fig. 8: In the inspector click on the plus sign to add a function to OnClick().

In the Button component there is a field called OnClick(), let’s click on the plus sign in the lower right corner, in figure 8 the cursor is over this button.

This will allow us to run public methods within the GameObject components we assign.

In the field that appears we are going to place the GameObject Control.

Fig. 9: A space appears for placing a GameObject.

Fig. 10: Place the Control object assigned to the GameController Script.

Ahora utilizando el menú desplegable, podemos acceder a las componentes y sus métodos.

Fig. 11: With the drop-down menu you can select a method from one of the components of the Control object.

Como se trata del botón Start, estamos buscando el método StartGame que hemos definido en el Script GameControl, en la figura 12 podemos observar los atributos y métodos públicos del Script GameControl y vemos que StartGame no se encuentra entre ellos.

Fig. 12: The startGame method does not appear between the functions.

This is because we use private visibility in the definition.

To solve the problem, we changed the method to public visibility, as shown in Figure 14.

Fig. 13: We had defined the startGame method as private.

Fig. 14: We change the visibility to public.

Ahora podemos elegir que se ejecute este método cuando se haga clic en el botón Start.

Fig. 15: The startGame method now appears in the functions.

I arrange the camera a little so that the small scene of the doors is seen and I enter the game mode to test the operation of the button.

Fig. 16: Arrange the main menu camera.
Fig. 17: Enter game mode to test the button.

Bug fixing

When entering game mode, the character appears on one of the doors randomly, but for some reason the controls don’t work properly, the character drags on the floor and the camera turns in a strange direction.

Fig. 18: The game starts but there seems to be a problem with the character.

Fig. 19: The character appears on the side and cannot move.

The Debugging process can be a bit tortuous, luckily we have tools to analyze the flow of the program, discover the parts of the code that work properly, see the values of the variables and so on to detect the problem and be able to correct it.

Without going into details, because I honestly don’t remember how I discovered the bug, the problem had to do with the hierarchy structure between GameObjects and the inherited transformation of the parent GameObject.

To correct the problem in the instruction to instantiate the character, within the “placePlayerRandomly” method, change the rotation from local to global, as seen in figures 20 and 21.

Fig. 20: The placePlayerRandomly method is the one that places the character on the stage.
Fig. 21: In the instantiate instruction we change localRotation for rotation.

This corrects the problem and we can use the start button to start the game.

Fig. 22: The character now appears correctly on the stage.

Final details

When you enter the game mode, the first-person controller prefab captures the cursor, places it in the center of the screen, and hides it.

This is a problem because when we return to the main menu when the game is over we can’t click on the buttons. So the solution is to unlock the cursor and make it visible at the end of the game, i.e. in the endGame() method.

To find out how to do this let’s analyze the MouseLook Script that uses the controller in the first person. In figure 23 we can see this Script along with its route to get to it.

Fig. 23: Abrimos el Script MouseMira dentro de FirstPersonCharacter de Standard Assets.

Fatal Error

When trying to open MouseLook the editor fails and must be closed losing all unsaved changes! It is important to save at all times, the CTRL+S access is very useful.

Fig. 24: When opening the script an error occurs and all unsaved changes are lost.

On the second attempt we were able to access the script. We are looking for an instruction related to the Cursor.

We see that in lines 93 and 94 of figure 26 there are a couple of instructions that seem to be the indicated ones so we copy them.

Fig. 25: Check the MouseLook script for instructions that unlock the mouse.

Fig. 26: The two selected instructions unlock the cursor and make it visible.

Then we go to the GameControl Script and paste these instructions at the end of the endGame method that will run when the time runs out.

Fig. 27: Paste the instructions at the end of the endGame method.

End the game

We are also going to give the user the possibility to end the game whenever he wants by using the Escape key.

We do this with the GetKeyDown method of the Input class.

In the first video of Unity’s fundamental series, I explain how to read keyboard and mouse entries, plus the difference between the different methods, there is also an article about the video on this page.

Fig. 28: Execute the endGame method by pressing the escape key.

Conclusion

In the article we discuss how to program the interaction between the user interface elements and the GameControl Script.

In the case of the button the functionality is already programmed for it to execute methods of the Scripts, but we must make sure that these methods have public visibility.

Leave a Comment

Your email address will not be published. Required fields are marked *

Exit mobile version