Adding Finesse to Your Game

Exclusive offer: get 50% off this eBook here
Ouya Unity Game Development

Ouya Unity Game Development — Save 50%

Your guide to building interactive media-rich 3D games with Ouya with this book and ebook

$17.99    $9.00
by Gary Riches | October 2013 | Games Open Source

In this article by Gary Riches, the author of Ouya Unity Game Development, we will see that as the Ouya technology is so new, finding information about developing for it can be hard, this article covers all that you'll need to know to create your game and add great features to it, such as controller functionality, animation, sounds, and monetization. We'll even show you how to make it work on Android phones and tablets.

(For more resources related to this topic, see here.)

Adding a background

There is still a lot of black in the background and as the game has a space theme, let's add some stars in there. The way we'll do this is to add a sphere that we can map the stars texture to, so click on Game Object | Create Other | Sphere, and position it at X: 0, Y: 0, Z: 0. We also need to set the size to X: 100, Y: 100, Z: 100. Drag the stars texture, located at Textures/stars, on to the new sphere that we created in our scene. That was simple, wasn't that? Unity has added the texture to a material that appears on the outside of our sphere while we need it to show on the inside. To fix it, we are going to reverse the triangle order, flip the normal map, and flip the UV map with C# code. Right-click on the Scripts folder and then click on Create and select C# Script. Once you click on it, a script will appear in the Scripts folder; it should already have focus and be asking you to type a name for the script, call it SkyDome. Double-click on the script in Unity and it will open in MonoDevelop. Edit the Start method, as shown in the following code:

void Start () {
// Get a reference to the mesh
MeshFilterBase MeshFilter = transform.GetComponent("MeshFilter")
as MeshFilter;
Mesh mesh = BaseMeshFilter.mesh;
// Reverse triangle winding
int[] triangles = mesh.triangles;
int numpolies = triangles.Length / 3;
for(int t = 0;t <numpolies; t++)
{
Int tribuffer = triangles[t * 3];
triangles[t * 3] = triangles[(t * 3) + 2];
triangles[(t * 3) + 2] = tribuffer;
}
// Read just uv map for inner sphere projection
Vector2[] uvs = mesh.uv;
for(int uvnum = 0; uvnum < uvs.Length; uvnum++)
{
uvs[uvnum] = new Vector2(1 - uvs[uvnum].x, uvs[uvnum].y);
}
// Read just normals for inner sphere projection
Vector3[] norms = mesh.normals;
for(int normalsnum = 0; normalsnum < norms.Length; normalsnum++)
{
[ 69 ]
norms[normalsnum] = -norms[normalsnum];
}
// Copy local built in arrays back to the mesh
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.normals = norms;
}

The breakdown of the code as is follows:

  1. Get the mesh of the sphere.
  2. Reverse the way the triangles are drawn. Each triangle has three indexes in the array; this script just swaps the first and last index of each triangle in the array.
  3. Adjust the X position for the UV map coordinates.
  4. Flip the normals of the sphere.
  5. Apply the new values of the reversed triangles, adjusted UV coordinates, and flipped normals to the sphere.

Click and drag this script onto your sphere GameObject and test your scene. You should now see something like the following screenshot:

Adding extra levels

Now that the game is looking better, we can add some more content in to it. Luckily the jagged array we created earlier easily supports adding more levels. Levels can be any size, even with variable column heights per row. Double-click on the Sokoban script in the Project panel and switch over to MonoDevelop. Find levels array and modify it to be as follows:

// Create the top array, this will store the level arrays
int[][][] levels =
{
// Create the level array, this will store the row array
new int [][] {
// Create all row array, these will store column data
new int[] {1,1,1,1,1,1,1,1},
new int[] {1,0,0,1,0,0,0,1},
new int[] {1,0,3,3,0,3,0,1},
new int[] {1,0,0,1,0,1,0,1},
new int[] {1,0,0,1,3,1,0,1},
new int[] {1,0,0,2,2,2,2,1},
new int[] {1,0,0,1,0,4,1,1},
new int[] {1,1,1,1,1,1,1,1}
},
// Create a new level
new int [][] {
new int[] {1,1,1,1,0,0,0,0},
new int[] {1,0,0,1,1,1,1,1},
new int[] {1,0,2,0,0,3,0,1},
new int[] {1,0,3,0,0,2,4,1},
new int[] {1,1,1,0,0,1,1,1},
new int[] {0,0,1,1,1,1,0,0}
},
// Create a new level
new int [][] {
new int[] {1,1,1,1,1,1,1,1},
new int[] {1,4,0,1,2,2,2,1},
new int[] {1,0,0,3,3,0,0,1},
new int[] {1,0,3,0,0,0,1,1},
new int[] {1,0,0,1,1,1,1},
new int[] {1,0,0,1},
new int[] {1,1,1,1}
}
};

The preceding code has given us two extra levels, bringing the total to three. The layout of the arrays is still very visual and you can easily see the level layout just by looking at the arrays.

Our BuildLevel, CheckIfPlayerIsAttempingToMove and MovePlayer methods only work on the first level at the moment, let's update them to always use the users current level. We'll have to store which level the player is currently on and use that level at all times, incrementing the value when a level is finished. As we'll want this value to persist between plays, we'll be using the PlayerPrefs object that Unity provides for saving player data. Before we get the value, we need to check that it is actually set and exists; otherwise we could see some odd results.

Start by declaring our variable for use at the top of the Sokoban script as follows:

int currentLevel;

Next, we'll need to get the value of the current level from the PlayerPrefs object and store it in the Awake method. Add the following code to the top of your Awake method:

if (PlayerPrefs.HasKey("currentLevel")) {
currentLevel = PlayerPrefs.GetInt("currentLevel");
} else {
currentLevel = 0;
PlayerPrefs.SetInt("currentLevel", currentLevel);
}

Here we are checking if we have a value already stored in the PlayerPrefs object, if we do then use it, if we don't then set currentLevel to 0, and then save it to the PlayerPrefs object. To fix the methods mentioned earlier, click on Search | Replace. A new window will appear. Type levels[0] in the top box and levels[currentLevel] in the bottom one, and then click on All.

Level complete detection

It's all well and good having three levels, but without a mechanism to move between them they are useless. We are going to add a check to see if the player has finished a level, if they have then increment the level counter and load the next level in the array. We only need to do the check at the end of every move; to do so every frame would be redundant.

We'll write the following method first and then explain it:

// If this method returns true then we have finished the level
boolhaveFinishedLevel () {
// Initialise the counter for how many crates are on goal
// tiles
int cratesOnGoalTiles = 0;
// Loop through all the rows in the current level
for (int i = 0; i< levels[currentLevel].Length; i++) {
// Get the tile ID for the column and pass it the switch
// statement
for (int j = 0; j < levels[currentLevel][i].Length; j++) {
switch (levels[currentLevel][i][j]) {
case 5:
// Do we have a match for a crate on goal
// tile ID? If so increment the counter
cratesOnGoalTiles++;
break;
default:
break;
}
}
}
// Check if the cratesOnGoalTiles variable is the same as the
// amountOfCrates we set when building the level
if (amountOfCrates == cratesOnGoalTiles) {
return true;
} else {
return false;
}
}

In the BuildLevel method, whenever we instantiate crate, we increment the amountOfCrates variable. We can use this variable to check if the amount of crates on goal tiles is the same as the amountOfCrates variable, if it is then we know we have finished the current level. The for loops iterate through the current level's rows and columns, and we know that 5 in the array is a crate on a goal tile. The method returns a Boolean based on whether we have finished the level or not. Now let's add the call to the method. The logical place would be inside the MovePlayer method, so go ahead and add a call to the method just after the pCol += tCol; statement.

As the method returns true or false, we're going to use it in an if statement, as shown in the following code:

// Check if we have finished the level
if (haveFinishedLevel()) {
Debug.Log("Finished");
}

The Debug.Log method will do for now, let's check if it's working. The solution for level one is on YouTube at http://www.youtube.com/watch?v=K5SMwAJrQM8&hd=1. Click on the play icon at the top-middle of the Unity screen and copy the sequence of moves in the video (or solve it yourself), when all the crates are on the goal tiles you'll see Finished in the Console panel.

Summary

The game now has some structure in the form of levels that you can complete and is easily expandable. If you wanted to take a break from the article, now would be a great time to create and add some levels to the game and maybe add some extra sound effects. All this hard work is for nothing if you can't make any money though, isn't it?

Resources for Article:


Further resources on this subject:


Ouya Unity Game Development Your guide to building interactive media-rich 3D games with Ouya with this book and ebook
Published: October 2013
eBook Price: $17.99
Book Price: $29.99
See more
Select your format and quantity:

About the Author :


Gary Riches

Gary Riches is a longstanding member of the iOS developer community. He has a keen interest not only in established sections of the industry such as gaming but also in emerging technologies such as Ouya, GameStick, and others.

Filled with a passion to program on new systems, he has just become a registered Wii U developer and will also create content for Xbox One and PlayStation 4. To target so many platforms he uses Unity, which he learned while working on the Augmented Reality SBook for Saddington Baynes.

When not building software for other companies, he builds his own business by creating photo manipulation apps such as Zombify Me, games such as Aztec Antics and Amazed, and also works on educational apps and games such as Nursery Rhymes: Volume 1, 2, and 3.

Books From Packt


CryENGINE 3 Game Development: Beginner's Guide
CryENGINE 3 Game Development: Beginner's Guide

AndEngine for Android Game Development Cookbook
AndEngine for Android Game Development Cookbook

Getting Started with Unity
Getting Started with Unity

Learning Stencyl 3.x Game Development: Beginner's Guide
Learning Stencyl 3.x Game Development: Beginner's Guide

Mastering UDK Game Development
Mastering UDK Game Development

SFML Game Development
SFML Game Development

jQuery Game Development Essentials
jQuery Game Development Essentials

 Learning ShiVa3D Game Development
Learning ShiVa3D Game Development


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
9
T
f
T
4
m
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software