UNITY 3D – Game Programming – Part 5 - CodeProject

:

Introduction

In part five of the series, we will bring together everything we have learned thus far, and move it up by a notch! We will look at how to import a 3D Model into the Game Engine and also using the methods we have learned so far, apply them to the movement in and around the world.

If you have not already done so, please take a moment and read:

  1. Unity 3D – Game Programming – Part 1

  2. Unity 3D – Game Programming – Part 2

  3. Unity 3D – Game Programming – Part 3

  4. Unity 3D – Game Programming – Part 4

  5. Unity 3D – Game Programming – Part 5

  6. Unity 3D – Game Programming – Part 6

  7. Unity 3D – Game Programming – Part 7

  8. Unity 3D – Game Programming – Part 8

  9. Unity 3D – Game Programming – Part 9

  10. Unity 3D – Game Programming – Part 10

Unity 3D Networking Article(s):

  1. Unity 3D - Network Game Programming

Unity 3D Leap Motion and Oculus Rift Article(s):

  1. Unity 3D - Leap Motion Integration

In the first part of the series we started by the very basics of the Unity 3D environment. Getting a feel of the IDE and the different sections which you will be working with throughout your project. We also covered how to use the tools in the designer to apply different transformation to a selected Game Object: positioning, rotation and scaling. We finally looked at how to create our first script and using the script apply a rotation transform on the Y-Axis of our cube.

In the second part of the series, we looked at more of the transformation of a given object through coding. We also looked at how to create light sources that are crucial for the rendering of your objects in the scene.

In the third part of the series we looked at how to process user input through the keyboard and based on the key code take particular actions.

In the fourth part of the series, we looked at creating a simple user interface. The user interface that we developed provided us a means to feedback to the user, and also another method for the user to input to our game or simulation.

In Part 5, we are going to use everything we have learned so far to make an interesting environment, where a player character can move around and discover object. Also, the key point in this article will be the method of importing a 3D model into the Game Engine.

Windows Phone 8.x Demo:

I have provided a free phone application that you can download and preview the demos on your Windows Phone. To download the mobile application, follow the link: CodeProjectArticleSample

https://www.codeproject.com/KB/game/876015/Icon_106.png
Code Project Articles Sample Mobile App

Live Preview of Article Code and Visuals:

https://www.codeproject.com/KB/game/876015/preview_screen.png

Link to live preview: http://www.noorcon.com/CodeProject/CodeProjectArticlePreview.html

Background

NOTE: For this particle, I will be using SketchUp to create some simple building blocks, which I will use to import into Unity! I am not a 3D Modeler or Designer, so please be patient and excuse the mess!

It is assumed that the reader of this article is familiar with programming concepts in general. It is also assumed that the reader has an understanding and experience of the C# language. It is also recommended that the reader of the article is familiar with Object-Oriented Programming and Design Concepts as well. We will be covering them briefly throughout the article as needed, but we will not get into the details as they are separate topics altogether. We also assume that you have a passion to learn 3D programming and have the basic theoretical concepts for 3D Graphics and Vector Math.

Lastly, the article uses Unity 3D version 4.6.1 which is the latest public release as of the initial publication date. Most of the topics discussed in the series will be compatible with older versions of the game engine, and perhaps also the new version which is supposed to be release sometime this year. There is however, one topics which is significantly different in the current 4.6.1 version compared to the older version of the game engine, and that is the UI (User Interface) pipeline. This is due to the new UI architecture in the engine which is far superior to what we had prior to this release. I for one, am very happy with the new UI architecture.

Using the code

Downloading the project/source code for article series: Download source.

With each consecutive article that is submitted, the project/source code will be also expanding. The new project files and source files will be inclusive of older parts in the series.

NOTE: To get the latest code, go to the most recent published part in the series and download the code.

The Idea

So as any other great achievement and project that is going on in the universe, the first step would be to come up with an Idea, a Vision of sort. So, for the purposes of this article and everything we have been doing in the series up-to this point, we would like to propose the following!

Brief:

Create a level that will resemble a maze. The level should be big enough to enable the player to freely move around and discover the level and all associated elements of that level. The level will be finite, and will have boundaries defined by walls. Let’s assume we want out level to be composed of a total of 100 square meters, therefore our main level will be a 10 meter x 10 meter square area. The objective of the player will be to pick up as many coins as possible in a given time.

NOTE: By all means, if you, at any time, want to contribute to any part of the series, please do so, and contact me so that we can incorporate your ideas and content into the series as well!

Let’s start by sketching out our environment, again me not being as creative as most of your out there, I came up with the following:

NOTE: This is not a SketchUp or a 3D Modeling article, so I will not be covering the use of the application.


Figure 1-SketchUp Model for My Level

I used SketchUp to create the desired maze I want for this demo. It is easy for me to use and since I am not a 3D Designer / Modeler. You can use any other tool that you are comfortable with. So here are the steps:

  1. Design the level in a 3D Modeling tool to your satisfaction.

  2. Export your model as an .OBJ file.

NOTE: In your 3D modeling software, you are capable of attaching textures to your model. I have not attached any textures to my model. At this point I am only interested with the structure of the model.

NOTE: When you are exporting your model make sure that you select the following options: Triangulate all faces is checked, Export two-sided faces is checked, and export the edges is checked as well. If you have attached any textures to your model, also check-mark the Export texture maps option.

Another important point you need to be aware of is the actual unit your modeling software is configured for. Since Unity 3D is in metric units, it is best to configure your 3D modeling software to use metric units for modeling.

NOTE: When exporting your model, also make sure that you are exporting in metric units. If your model is already in metric units, select Model Units.

So now let’s see how easy it is to import our model into Unity 3D.

Importing the Model:

The first thing I would like to do is create a directory structure that would be easy for navigation within the project. I keep it pretty simple. I have a folder for each different type of asset I will be using in my project. So a given project has at least the following folder under the Assets folder:

  • Models – all my models are kept in this folder.

  • Prefabs – all my prefabs are kept in this folder.

  • Scenes – all my scenes are saved in this folder.

  • Scripts – all my scripts are saved in this folder.

  • Sprites – all my sprites (2D textures) are saved in this folder.

You can create this directory structure directly from within Unity 3D, or at the file system level, where your project is stored. To create it within the IDE, you will need to Right-Click in the Project window and select Create->Folder from the Context Menu.


Figure 2-Project Structure for Demo

To import your model, you can simply copy and paste your .OBJ file in the models folder. This can be done through your system’s file explorer to copy and paste any other file. Once you copy the .OBJ file in the desired folder, come back to Unity 3D, and the engine will automatically apply the proper internal markings to your .OBJ file or files.


Figure 3-Project View after Placing .OBJ File in Model Folder


Figure 4-Inspector Window for Model

After you import your model, from the Project Window, navigate to your model and select it.

Your Inspector Window should now display all of the properties for your model.

There is a lot of attributes as shown in Figure 4, and each one is important. Some are checked by default. And depending on your model and the use of your model, the purpose, you will turn on or off these attributes as you see fit. You will need to do more reading on this on your own.

But for our purposes, and in most cases, the default settings are sufficient. The only change we need to do is enable the Generate Colliders feature, as shown in in Figure 4, item number 2.

The colliders are an important part of the model, and we will cover this in more details later. The colliders are used for collision detection.

The next two important attributes are the Normals and Tangents which are imported automatically and calculated automatically by the engine, number 3, in Figure 4.

In the Inspector Window, scroll all the way down and click on the Apply button. Now Unity will apply all of the necessary changes to your model.

Creating the Level:

Let’s begin our new level by creating a new scene. You can do this by selecting File->New Scene from the main menu.

NOTE: If your current scene is not saved, you will be prompted to save it.

Now drag and drop your model from the Project Window into the Scene Designer View.


Figure 5-Imported Model in Design View

I have adjusted my view and the camera to get a better idea of how the level look in the 3D space. Also, what I did is position the level model to the following coordinates: <5,0,5>; this technically centers the model to the origin, since my model is 10 x 10. I also placed a light source at the origin to give some light to the scene for better viewing.

That’s all you need to do as far as placing the model in the scene is concerned. So we are done with this stage. Now let’s look at the next step in our game.

Creating and Placing the Player Character:

Since our game is composed of a maze, and the player in the game is supposed to gather as many coins as possible in a given amount of time, I have decided to model my player as a sphere. So we will use a sphere primitive as a place holder for our main character. To do so, in the Hierarchy Window right-click and select 3D Object->Sphere.


Figure 6-Create Sphere as Placeholder for Player Character

NOTE: When you create your Sphere object, use the design positioning tools to place it properly above and within the level model.


Figure 7-Inspector Window for Player Placeholder

Your Inspector Window should now display all of the properties for your model.

First thing I would like to do is change the name of the GameObject from Sphere to CharacterPlaceHolder_Part_5.

The second and more important change that we need to do to this GameObject is to add a Rigidbody component to it.

In order to do so, you will need to select Add Component button in the Inspector Window, and select Physics and then Rigidbody.

Adding a Rigidbody component to an object will put its motion under the control of Unity's physics engine. Even without adding any code, a Rigidbody object will be pulled downward by gravity and will react to collisions with incoming objects if the right Collider component is also present.

This will be enough for what we are looking for simulating the motion and also collision with other objects in the scene.

NOTE: I have set the Freeze Rotation on the X and Z Axis.

This is to stop the object rotate in those axis based on the forces developed within the environment. For example we don’t want our object to do rotation on the X and Z Axis if it collides with another object.

 

The next thing I want to do is be able to move the Character Player (CP) in the scene. In order to do this, we need to create a script and attach it to the object representing our CP. I call that script playerInput.cs and here is the listing for it:

using UnityEngine;
using System.Collections;

public class playerInput : MonoBehaviour {

 // Use this for initialization
 void Start () {
 
 }
 
 // Update is called once per frame
 void Update () {
  // code for the movement of player (CP) forward
  if(Input.GetKey(KeyCode.UpArrow)){
   this.transform.Translate(Vector3.forward * Time.deltaTime);
  }
  // code for the movement of player (CP) backward
  if(Input.GetKey(KeyCode.DownArrow)){
   this.transform.Translate(Vector3.back * Time.deltaTime);
  }
  // code for the movement of player (CP) left
  if(Input.GetKey(KeyCode.LeftArrow)){
   this.transform.Rotate(Vector3.up, -5);
  }
  // code for the movement of player (CP) right
  if(Input.GetKey(KeyCode.RightArrow)){
   this.transform.Rotate(Vector3.up, 5);
  } 
 }
}

Our CP movement is very simple really. We will be using our keyboard arrows to define the movement of the CP. The Up and Down keyboard arrows will move the CP forward and backward respectively, and the left and right keyboard arrows will rotate the CP left or right respectively.

One more last thing I would like to do to our scene (level) is to make the Camera follow the CP. This is also very easy to achieve!

In the scene designer, use your mouse to position your view in the scene designer behind the CP, the Sphere.


Figure 8-Game View Showing Actual Camera View during Game Play

When you are satisfied with what you see in the Scene Window, select the Main Camera object. From the main menu, select GameObject->Alighn With View. This will move the Main Camera GameObject, or the current selected GameObject, to be aligned with the view in the scene!

You can now run the program and be able to move in the designed level:

Creating the Coins:

Ok so now that we have our main level design in place and our CP also in place and movable, we can start working on the coins! To design the coin, I have used the Capsule primitive. So to create the coin, in your Hierarchy Window, right-click to get the Context Menu, and select 3D Object->Capsule.


Figure 9-Capsule Primitive after Modifications

This will place a capsule primitive on the scene. We would need to modify the properties of our capsule game object to make it look like a coin, to do so, we will need to work with the Inspector Window.


Figure 10-Coin GameObject Inspector Window

Your Inspector Window should now display all of the properties for your model.

First thing I would like to do is change the name of the GameObject from Capsule to coin.

The second change I would like to make is to change the Scale attributes of the GameObject. I want to make it look more like a coin, so in order to do so, I have to change the scale to the following: <0.25, 0.05, 0.25> respective to each axis. Also rotate the GameObject 90 degrees on its Z-Axis. Rotation should be: <0,0,90>.

The third important property change is to set the Is Trigger property on the Capsule Collider to True. This is important for collision detection in the engine. It allows to raise an event when the collider of this GameObject hits/enters the collider of another GameObject.

Lastly, I would like to make the coin rotate in the scene for some dynamism and extra effect in the level. Therefore, we will attach a rotation script to the coin GameObject called rotateCoin.cs.

NOTE: Since I had to rotate my original Capsule primitive on it’s Z-Axis 90 degrees, the rotation axis of the coin object is not going to be on the Y-Axis anymore. The new axis of rotation will be the X-Axis based on my design. Yours might be different!

NOTE: I have also created a new Tag called coin.

The Tag element is another attribute that can be used to identify the user defined type of a GameObject. By default, you will only have the following Tags:

  • Untagged

  • Respawn

  • Finish

  • EditorOnly

  • MainCamera

  • Player

  • GameController

To add a new tag, you will need to select Add Tag… and enter your Tag in the list element. In this case, I created a new tag called coin and changed the Tag attribute from Untagged to coin in the Inspector Window.

Now you can run the program to test the new implementation. Your coin should be rotating in its location as positioned in the world.

Listing for rotating coin:

using UnityEngine;
using System.Collections;

public class rotateCoin : MonoBehaviour {

 // Use this for initialization
 void Start () {
 
 }
 
 // Update is called once per frame
 void Update () {
  this.transform.Rotate (Vector3.right, 3);
 }
}
Detecting Collision:

The objective of our game is to pick-up coins. In order to do so, we need our CP to be able to detect if it has collided/intersected a coin object or not. To do so, we need to expand the script attached to the CP to handle this event.

Since this is a simple game with not too many interactions and logistics, we can use the same script that handles the player’s input to also address the collision detection. So we can expand out playerInput.cs script to the following:

using UnityEngine;
using System.Collections;

public class playerInput : MonoBehaviour {

 // Use this for initialization
 void Start () {
 
 }
 
 // Update is called once per frame
 void Update () {
  // code for the movement of player (CP) forward
  if(Input.GetKey(KeyCode.UpArrow)){
   this.transform.Translate(Vector3.forward * Time.deltaTime);
  }
  // code for the movement of player (CP) backward
  if(Input.GetKey(KeyCode.DownArrow)){
   this.transform.Translate(Vector3.back * Time.deltaTime);
  }
  // code for the movement of player (CP) left
  if(Input.GetKey(KeyCode.LeftArrow)){
   this.transform.Rotate(Vector3.up, -5);
  }
  // code for the movement of player (CP) right
  if(Input.GetKey(KeyCode.RightArrow)){
   this.transform.Rotate(Vector3.up, 5);
  } 
 }

 // This event will be raised by object that have their Is Trigger attributed enabled.
 // In our case, the coin GameObject has Is Trigger set to true on its collider.
 void OnTriggerEnter(Collider c){
  if(c.tag.Equals("coin")){
   Debug.Log("Got the Coin!");
  }
 }
}

The main function that handles the trigger event is OnTrigeerEnter(Collider c). This function will get the collider of the object that is entering the collider of the CP objet. In the collider, we check to see what kind of an object we have collided with, and to do so, we are using the Tag element attached to the GameObject we are colliding with!

In this case, we are going to print out to the console window “Got the Coin!” each time we collide with an instance of the coin object.

Points of Interest

We covered a huge amount of ideas and concepts in Part 5. We discussed briefly how to start with developing an idea and a vision and setting game rules and boundaries on paper before we start any designing and coding. We looked at how to import a 3D model into Unity 3D. We looked at how to create a Character Player (CP) and how to apply movement to it.

We also discussed how to add components to a given GameObject. For instance, for the CP, we had to add a Rigidbody component. This allows us to use the physics engine to start creating more lifelike interactions within the world.

We also looked at the Is Trigger attribute in the Collider component of the coin GameObject.

All in all, there is a lot of information that we covered in the article in a very short and simplified way. The idea is for you to dig deeper and become more familiar with them on your own.

In the next part, we will continue with our game and start introducing more interaction and also start developing some GUI (Graphical User Interface) for it.

History

This is the fifth article of a series which I would slowly contribute to the Code Project community.

  1. Unity 3D – Game Programming – Part 1

  2. Unity 3D – Game Programming – Part 2

  3. Unity 3D – Game Programming – Part 3

  4. Unity 3D – Game Programming – Part 4

  5. Unity 3D – Game Programming – Part 5

  6. Unity 3D – Game Programming – Part 6

  7. Unity 3D – Game Programming – Part 7

  8. Unity 3D – Game Programming – Part 8

  9. Unity 3D – Game Programming – Part 9

  10. Unity 3D – Game Programming – Part 10

Unity 3D Networking Article(s):

  1. Unity 3D - Network Game Programming

Unity 3D Leap Motion and Oculus Rift Article(s):

  1. Unity 3D - Leap Motion Integration