- Unity Android Game Development by Example Beginner's Guide
- Thomas Finnegan
- 1482字
- 2025-04-04 22:06:41
Time for action – creating Tic-tac-toe
The basic Tic-tac-toe game involves two players and a 3 x 3 grid. The players take turns filling X's and O's. The player who first fills a line of three squares with his/her letter wins the game. If all squares are filled without a player achieving a line of three, the game is a tie. Let's perform the following steps to create our game:
- The first thing to do is to create a project for this chapter. So, start up Unity and we will do just that.
- If you have been following along so far, Unity should boot up into the last project that was open. This isn't a bad feature, but it can become extremely annoying. Think of it like this: you have been working on a project for a while and it has grown large. Now you need to quickly open something else, but Unity defaults to your huge project. If you wait for it to open before you can work on anything else, it can consume a lot of time. To change this feature, go to the top of the Unity window and click on Edit followed by Preferences. This is the same place where we changed our script editor's preferences. This time, though, we are going to change settings in the General tab. The following screenshot shows the options present under the General tab:
- At this moment, the primary concern is the Always Show Project Wizard option; however, we will still cover all of the options in turn. All the options under the General tab are explained in detail as follows:
- Auto Refresh: This is one of the best features of Unity. As assets are changed outside of Unity, this option lets Unity automatically detect the change and refresh the asset inside your project.
- Always Show Project Wizard: This is a great first option to go check whenever installing Unity. Instead of opening the last project, Unity opens Project Wizard. From there, you can open any project of your choice or create a new one. This is always a good one to turn on.
- Compress Assets on Import: This is the checkbox for automatically compressing your game assets when they are first imported to Unity.
- Editor Analytics: This is the checkbox for Unity's anonymous usage statistics. Leave it checked and the Unity Editor sends info occasionally to the Unity source. It doesn't hurt anything to leave it on, and helps the Unity team make the Unity Editor better. But it comes down to personal preference.
- Show Asset Store search hits: This setting is only relevant if you are planning to use the Asset Store. The Asset Store can be a great source of assets and tools for any game; however, since we are not going to use it, the relevance to this book is rather limited. It does what the name suggests. When you search the Asset Store for something from within the Unity Editor, the number of results is displayed based on this checkbox.
- Verify Saving Assets: This is a good one to be left off. If this is on, every time you click on Save in Unity. A dialog box will pop up so that you can make sure you save any and all of the assets that have changed since your last save. It is not so much about your models and textures, but concerned with Unity's internal files, the materials, and prefabs. Best to leave it off for now.
- Skin (Pro Only): This option only applies to Unity's pro users. It gives the option to switch between the light and dark versions of the Unity Editor. It is purely cosmetic, so go with your gut for this one.
- With your preferences set, now go up to File and follow it with selecting Open Project.
- Select the Create New Project tab, followed by the Browse... button to pick a location and name for the new project.
- We will not be using any of the included packages, so click on Create and we can get on with it.
- Once Unity finishes initializing the new project, create two new scripts in the Project panel, just as we did for the Hello World project in the previous chapter. Name the new scripts as
TicTacToeControl
andSquareState
. Open them and clear out the default functions; again, just as we did in Chapter 1, Saying Hello to Unity and Android. - The
SquareState
script will hold the possible states of each square of our game board. To do that, clear everything out of the script and replace it with a simple enumeration. An enumeration is just a list of potential values. This one is concerned with the player who controls the square. Do X's control it, O's control it, or is it clear because the game board is traditionally clear by default.Clear
becomes the first and therefore the default state.public enum SquareState { Clear, XControl, OControl }
- In our other script,
TicTacToeControl
, we start with two variables that will largely control the flow of the game. The first defines our game board. Traditionally the game is played on a 3 x 3 grid, therefore nine squares. The second line dictates whose turn it is. How it is going to change will be made clear in a little bit, but for now suffice it to say that if it is X's turn, the value will be true. If it is not X's turn, the value will be false.public SquareState[] board = new SquareState[9]; public bool xTurn = true;
Tip
In Unity, every script by default inherits from the
MonoBehaviour
class. This gives our scripts two primary benefits.First, it allows us to add our scripts to objects as components. The filename of the script also needs to be the exact same as the class name within the script, if you plan on adding the script to an object.
The second benefit of the
MonoBehaviour
class is the variety of variables and functions that come with it. The variables give us access to all the parts that make up objects in Unity. The functions provide a number of automatic features and access to the game initialization and loop. This is what we are most interested in at this particular moment. - In order to draw anything in each GUI frame, one needs to utilize the
OnGUI
function provided by theMonoBehaviour
class. That is where we will draw our game board. TheOnGUI
function lets us draw our interface every frame. Inside it, we will first define the width and height of our board squares.public void OnGUI() { float width = 75; float height = 75;
- Following that is a pair of for-loops. Because our board is a 3 x 3 grid, we need the loops to count three rows of three squares.
for(int y=0;y<3;y++) { for(int x=0;x<3;x++) {
- Inside the loops we must first figure out which square we are currently drawing. It becomes hard to play a game, if you don't know which square was touched.
int boardIndex = (y * 3) + x;
- The next line of code defines whether the square is going to be drawn as a
Rect
class. ARect
class is defined in GUI space as x position, y position, width, and height. In Unity, GUI space is defined as the top-left corner being (0,0) and the bottom-right isScreen.width
,Screen.height
. The width and height of the screen are the number of pixels.Rect square = new Rect(x * width, y * height, width, height);
- We then figure out who controls the square. The following line of code is a little complicated, but it is really just a compressed
if
statement. Basically, it works like this: first check a condition and if it is true return the first value, whatever is between the question mark and the colon. If the condition is false, return the value after the colon. Two of these compressedif
statements were combined here; if the square is owned by X, set our owner to X. Otherwise, if it is owned by O, set the owner to O. If neither of the conditions is true, nobody owns the square and we set our owner to an empty string.string owner = board[boardIndex] == SquareState.XControl ? "X" : board[boardIndex] == SquareState.OControl ? "O" : "";
- Now that all the hard work of figuring out where we are is done, we actually draw our game board square. This is done through the use of a wonderful little function provided by Unity,
GUI.Button
. To use this function in its basic form, we must tell the function where the button should be drawn and what text to display, hence rect and string. We give it our square and owner variables, it does all the hard work of actually drawing on screen, and we are given back a Boolean result, whether or not the button was pressed. Therefore, we check it with anif
statement and if true, we send to a new function which square was pressed, letting it handle setting the owner. Also, don't forget the extra curly braces to close up the loops and the function.if(GUI.Button(square, owner)) SetControl(boardIndex); } } }
- The
SetControl
function is pretty short; it simply sets the owner for whichever square is passed to it. It first makes sure that the index given is actually within the range for our board. If it is not, we'll exit the function early. The next line of code sets control of the board square based on whose turn it is. If it is X's turn, set the square toXControl
; otherwise set control toOControl
. Finally we change whose turn it is. This is done by simply setting ourxTurn
Boolean to the opposite of itself, indicating that it is the other person's turn.public void SetControl(int boardIndex) { if(boardIndex < 0 || boardIndex >= board.Length) return; board[boardIndex] = xTurn ? SquareState.XControl : SquareState.OControl; xTurn = !xTurn; }
- We are just about ready to play our game. We just need to set up the scene. To do this, start by dragging our
TicTacToeControl
script from the Project pane of the Unity Editor to the Main Camera object in the Hierarchy pane of the Unity Editor. - Now save the scene, just as we did in Chapter 1, Saying Hello to Unity and Android, as
TicTacToe
. - It is possible to play the game at this point. It is also possible to do so on a device; just follow the same steps as in Chapter 1, Saying Hello to Unity and Android, but for now just perform testing in the Unity Editor. Later in this chapter we will cover a much easier way to build to our devices.
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
What just happened?
We created the very base of what we need to play Tic-tac-toe. We did this with two short and simple scripts. However, while playing the game now, you probably noticed a few things about it. For starters, it doesn't look particularly fantastic. That is extremely odd, considering it is the point of this chapter, but we will address that soon enough. Second, there are no checks to determine whether or not somebody already controls a square.
Also, there are no checks to see if anybody won the game. Finally, if you decided to build to device, you might have noticed one of the great things about Unity's GUI functions. There is no special programming needed to make any of the GUI functions work with touch inputs rather than the mouse. A lot of time is saved when you don't have to worry about special inputs, especially if you plan on multiplatform targeting.