Megabite #6 - Creating an Android Game From Scratch (Part 2)

In the last article, we set up a basic framework that used the accelerometers of our device to manipulate our little cube.  Obviously if our game was more finalized we would want to hide all the debugging numbers and such completely, but for now, lets simply toggle them on and off by using the "back" button on the device.

Android registers this button as "escape", which is effectively like pushing the escape button on your keyboard.  This is handy because it will allow us to test our functionality quickly.

To begin, let's use our existing script for movement (mine was called "cubemover"), and set up a private variable called overlayOn.  Because this is an off/on variable (this is called a "boolean"), we will set it to false by default, like this:

private var overlayOn = false;

Next, we just need a way to toggle it.  This script will go into the Update() section of the script to listen for our key press.

//Making use of the Android "Back" Button
if (Input.GetKeyDown(KeyCode.Escape)) {
	if (overlayOn == false ) {
	overlayOn = true;
	} else {
	overlayOn = false;
	}
}

The last thing to do is simply encase our GUI script elements in an IF statement.  With everything together, the whole script should end up like this:

var dir : Vector3 = Vector3.zero;
private var calibrateX : float = 0;
private var calibrateY : float = 0;
private var overlayOn = false;

function Update () {
		//In landscape mode, +X is up, -X is down, +Y is left and -Y is right
	dir.x = Input.acceleration.x;
	dir.y = Input.acceleration.y;
	dir.z = Input.acceleration.z;

	if (dir.sqrMagnitude > 1) {
		dir.Normalize();
	}
	//left/right
	transform.position.x = (transform.position.x - (dir.y - calibrateY));
	//up/down
	transform.position.y = (transform.position.y + (dir.x - calibrateX));
//Making use of the Android "Back" Button
if (Input.GetKeyDown(KeyCode.Escape)) {
	if (overlayOn == false ) {
	overlayOn = true;
	} else {
	overlayOn = false;
	}
}
}
function OnGUI() {
if (overlayOn == true) {  // only display if Overlay is toggled on.
	GUI.Label(Rect(4,4,300,30), "dir.x: " + dir.x);
	GUI.Label(Rect(4,44,300,30), "dir.y: " + dir.y);
	GUI.Label(Rect(4,84,300,30), "dir.z: " + dir.z);
	//Button to Reset to center position
	if (GUI.Button (Rect(Screen.width /2 - 60, Screen.height /2 - 120, 120, 50), "Reset")) {
	transform.position = Vector3(0,0,0);
	}
	//Button to recalibrate Zeroed control center
	if (GUI.Button (Rect(Screen.width /2  - 60, Screen.height /2 - 65, 120, 50), "Calibrate")) {
	calibrateX = dir.x;
	calibrateY = dir.y;
	}
	//Button to exit program
	if (GUI.Button (Rect(Screen.width /2  - 60, Screen.height /2 - 10, 120, 50), "Exit Game")) {
	Application.Quit();
	}
}
}

As an added bonus, I added in a third button that will actually exit the program as well.  When saved and run, everything will disappear until we hit our escape key.  after we do, we see this:

On the next page, we're going to import some assets to use for the first time and get rid of that blue background. :)

Now that we've got these essentials all put together, let's work for a bit on the look and feel of the game.  Right now, the cube sort of floats in space, and our goal here will be to drop it onto a fancy textured wooden plane.

First, start by opening the Asset Store from the menu.  The store is comparable to any other digital store, but these assets (a mix of free or buyable) are made especially for use in Unity.  We're going to get ourselves a pack of free textures that I've grown to love.

You can use the search tool to find the entry called "Eighteen Free Substances", which has everything including brick, stone, wood, metals, and a few other gems.

If this is your first go-round with the store, be sure to create an account - there are many useful tools within.  Once you are able, download and import these assets right into your project.

(As a side note, if you choose to pay for assets in the future, just know that you only have to purchase them once.  They will be available to import into any future project with ease.)

In the Hierarchy, create a "plane" on your scene.You can see in the picture that I've rotated mine to face the camera and located it behind the cube.  In the "materials" section of the inspector, you can drag and drop the material of your choice.  As I am going for a wooden look, I chose the "wood plank" asset to add.

You can see the results of your choices immediately within the scene window.  The Scale of your plane will need to be different for your intended device, but a see bet would be to make it fairly large at this point and scale it down if needed.  For me, I simply scaled x,y and z to 6.

When you scale your plane, you will see your material stretch out.  Not to worry - the creators of this asset pack enabled you to further delve into options to customize things however you like.

Depending on the material you chose, you will have an array of different options.  In the image to the left you can see the beginnings of these options toward the bottom of the inspector window.

With this setup, you might already see what this project will look like when played, but you should always test your project to really get a good view.  If things have suddenly become darker than you like, you can also use the Hierarchy to add a directional light to your project which can be adjusted to really customize the view.

Follow me onto the next page, and we'll get into how gravity works within our game, and how to really tune it ourselves.


Right now, gravity doesn't affect our little cube at all.  If it did, Unity's default setting would send it downward against the Y axis, which wouldn't be ideal for what our goal is.  We want our cube to fall away from the camera - basically, downward against the Z axis.  Luckily, changing this is a snap.

In the Physics settings of our game, we end up with options mainly pertaining to Rigidbodies, which are GameObjects that are physics sensitive.  If we want anything to act "physical", we want to add the Rigidbody component to it as well as really tune what that means to get the best results.  For now, we simply want to change the default gravity, as seen here:

I've left all other settings at their default values for now, but we can always come back.

Next, let's get physical.  On your cube object, we want to add the rigidbody component we were just talking about.  Simply select your cube and use the main menu: Component -> Physics -> Rigidbody.

Before you play your game, let's make sure we fully understand what this means.  Basically, a GameObject with a Rigidbody will have weight, velocity, and other sub-components that can be tweaked to our liking.  Upon playing the game, you will immediately see the cube fall onto the plane - and depending on the distance you may even see it bounce a bit.  This is normal, because the cube is now under the control of the Unity physics engine as well.

What we're going to ultimately do is set the stage to have a player manipulate their device using tilt controls and attempt to get our game piece into a hole that we create.  When they do, they register a victory, and we can move on from there.  For this portion of the design process, we are going to use less scripting and more artistic methods.  

Unity can create simple polygons, but to really have fine control over the 3d models, you will want to use the program in conjunction with any available 3d modeling application.  On the next page, I will go into the basics that I used to create the plane-with-a-hole that we will need to achieve our goal.

 I prefer to program on my MacBook, and the modeling application I have for basic stuff is called Cheetah3d.  While it may not be as advanced as some other option out there, it does the job for simple polygon manipulation and even handles animations when needed.  Because everyone will be different in what they choose to use, I will simply say that what I created was an object that measures 16x10x1, and I placed a square divot into the upper-right corner, like so:

While one might assume that it would be difficult to get a 3d model into our game, we can simply save the file directly to the asset folder, or we can use the import options within our project window.

Whichever way you find is best, you should have little issue getting your model into the game itself.  Your assets should even update automatically if you edit your file further and save it once again.

Once you have the file imported, you can drag it onto the scene and position/scale it accordingly.  When you playtest your game, everything should look as intended - except your cube might appear to fall right through your new 3d model.  Why is this?  Well, your model may exist, but it is going to need a "collider" in order for it to react to something smacking into it.  Colliders are the invisible walls that exist within games, (for those of you that have ever turned off "clipping" within a game, this is what you're toggling.)  they react to other colliders, and by default will not fall through each other.

While we have a few choices for colliders to use, our best bet here will be a "mesh collider", which follows the wireframe of your new 3d model and will allow the cube to fall into the hole we've created.

Since we're already in the process of making the game more fancy looking, let's give our cube a makeover and actually turn it into something more marble-like.  Start by creating a sphere via the hierarchy and placing it at position 0,0,0 (the same location as the cube).  Then, drag the movement script onto our sphere and name it whatever you like.  After that's done, you can feel free to delete our trusty cube from the game - we had a good run, but cubes don't roll all that well.  Be creative with your sphere and give it a makeover using the substance pack we imported earlier.

Placement: for easy viewing, I made our original plane completely black and placed it within the 3d model that we've added.  While you don't have to change your coloration unless you choose to, I wanted to be sure that your game looks similar to this on your screen:

 

The placement of your original plane will be important because falling onto that plane is what will trigger "victory" when we add the code for it.  Once you have it the way you like it, you can drag the plane onto the 3d model within the Hierarchy to effectively make it a GameObject with an attached child object.

On the next page, we'll finish this week's lesson by enabling you to create the obstacles that your player will encounter within the game.

What's a game without a challenge?  Really, we could add anything eventually - enemies with AI, turrets with lock-on targeting, mines or fires, etc.  However, starting with the basics will be the best way to learn.  Because Unity objects created within the Hierarchy will automatically have colliders attached and are easily manipulated, we can use those to create basic block walls and develop a maze of our own.

While I won't dictate exactly what patterns you should use or how to lay out your level, I will say that you should test your layout often and look at it from all angles.  Also, I need to mention that we have not completed the scripting that will make up the movement of our game piece.  You will likely see the marble make its way through walls and obstacles because we aren't adding a force to the rigidbody, we are currently just manipulating its world position.  As it stands, the only real physics applied are simply the result of gravity.

Regardless of if you choose to manipulate the level itself (if you have an existing working knowledge of 3d modeling, this might be a fun way to go), or if you simply add a multitude of different cubes and cylinders, spend as much time as you can developing the level into something you can be proud of.

Next week we will cover the manipulation of force, the triggering of object collisions, and perhaps even work in some pitfalls that might cause our little marble to explode.  Thanks for reading, and stay tuned!