This is a tutorial by Joshua Newnham, the founder of We Make Play, an independent studio crafting creative digital play for emerging platforms.
Unity is arguably the most popular 3D game engine for iOS – and for many good reasons!
- Rapid development. Writing your game with Unity is far quicker than trying to write your own 3D engine, or than using lower level 3D frameworks.
- Visual scene layout. Unity comes with a powerful 3D scene editor that you can use to design a huge part of your app – often without having to write code!
- Cross platform. If you write your game with Unity, you can deploy it to iOS, Android, Windows, Mac, or even the web!
- Easy to learn. Unity is far easier to learn than straight OpenGL or lower level frameworks. It’s friendly to beginners and is easy to get started!
We just released an epic three-part Beginning Unity 3D for iOS series, but if you’re itching to learn more, we’ve got you covered!
This time, you will create a simple but fun 3D basketball game called “Nothing but Net.” Along the way, you’ll cover the major concepts used in Unity and will be ready to create your own apps!
Some of this tutorial will be review, but you’ll learn a ton along the way since this game is much more complicated than the “Heroic Cube” game ;]
Note: This tutorial was made with Unity 3, so there may be some slight differences with Unity 4.
Shall we play a game? :]
Designing the App
As with any app, before you begin coding you should first determine what it is you’re making – and why! You should figure out your target audience, what your idea is and why it appeals to them, and what features the app should have.
Let’s give this a shot!
For this tutorial, let’s assume your target audience is a male between the ages of 12-35 – let’s call him Bryan. Bryan is:
- a 33 year old Accountant
- owns an iPhone
- is interested in sports
- is an office dweller with an average commute time of 20 min per day on public transport.
Like most smartphone users, Bryan’s iPhone is a regular form of entertainment during commuting, and in general, every spare moment when he is alone – and even sometimes when he’s bored at dinner, much to his wife’s annoyance!
Your goal will be to create something that offers Bryan a chance to escape for a few minutes during his day. You’ll create a very simple (but fun!) app with just a single and easy to learn mechanic. This way, it can be easily picked up and used in a noisy and disruptive environment, such as commuting.
As your target audience is males between the ages of 12-35, your theme for the game will be sport related. Mobile casual game play typically ranges between 4-8 minutes so aim for a complete gaming session — including loading and starting the game — to last 5 minutes.
So – you want a simple mechanic, and a quick sports-related game. How about shooting a basketball? Here’s a sketch of what it could look like:
Ah – you’re getting somewhere! Time to flesh out the functionality and components you will need!
- Goal: score as many points as possible within the time limit
- To throw the ball, the player taps and holds their finger on the screen. The longer their finger is held down the harder the ball will be thrown. Leaving it down too long will raise a foul.
- Visually rich and engaging to attract the player
- Simple support menu (overlay the game screen with the option to start the game)
- Realistic physics to allow for rebounds
- Increase the difficulty by moving the avatar around the court more frequently as time passes and the player gets more comfortable with the game).
Game assets and their features:
- Idle animation
- Throw animation
- Move animation
Okay, now that you have the basic design of the app down, it’s time to start creating! :]
Introducing Unity 3D
If you already have Unity, feel free to skip this section.
Otherwise, you need to download Unity before you can proceed! You can download a free trial at the Unity website. Simply run the installer, and you’ll be ready to start using Unity.
Unity is free for non-commercial use, but you do need to register it in order to use it for your projects — hence the Register button you will see on first use. Once Unity is launches, the AngryBots sample project will appear.
You want to start with a new project, so select File\New Project from the main menu and save it wherever you want. Don’t worry about selecting packages to import just now.
Your first time opening Unity (after having registered), you will probably see:
Note: The introductory videos and manuals listed here are helpful resources to check out after you finish going through this tutorial – they will give you a good overview of Unity and what it’s capable of. For a more comprehensive review, check out the official documentation at http://docs.unity3d.com/Documentation/Manual/LearningtheInterface.html.
Before you get started, have a quick look at Unity’s user interface, which will become the command center for all of your Unity projects! :]
The Unity Interface
Let’s do a quick review of the Unity Interface. If you’re already comfortable with this, feel free to skip to the next section.
Unity’s UI is made up of 5 individual panels, each tightly related, but giving you a different perspective of the project.
First, the Project panel provides you with an overview and quick access to all the assets of your game. “Assets” means any resources that your game will use, such as scripts, textures, sounds, and data files.
Note that some of the folder names that will appear in this panel are used for specific tasks. For instance, when using graphical elements for “Gizmos”, which are design time icons, you need to place them in a “Gizmo” folder so Unity knows where to search for them.
Second, the Hierarchy panel is a view of all assets that are in the current scene. This allows you to quickly select items without having to navigate through the 3D view or perform a multi-select. A quick tip — to get focus of a particular asset, hover your mouse over the item you want to focus on in the Scene panel and tap the ‘F’ key.
On to the Camera panel! This gives you the point of view of the camera(s) in the scene. Note the three toggle buttons at the top right. Maximize on Play maximizes the window when you select Play. Stats is handy when you are ready to optimize your app, as it will show you draw calls and other useful stats. Gizmos allows you to show and hide specific Gizmos in the game scene.
The panel above the Camera panel is where you’ll spend most of your time designing your levels. This is the Scene panel which allows you to visually design your level. If you’re familiar with 3D modeling tools, then you should feel pretty comfortable here! :] If not, don’t fret — Unity is pretty intuitive and easy to learn.
The selected item, including the camera, can be manipulated using the manipulation tools at the top of the window:
The hand tool allows you to pan around the scene. The translation tool will show handles on the selected item, allowing you to move, or translate, the item around the scene. Rotation and scale allow you to manipulate the selected item by rotating or scaling it.
Note: It’s worth getting comfortable with the short-cuts to these tools. It’s pretty easy to remember them; they’re the first four letters on the keyboard and they correspond in order to the four tools: Q (Hand), W (Translate), E (Rotate), and R (Scale). Don’t forget your good friend F to focus in on the selected item — you will use F a lot! :]
A quick note about Scale: it’s best not to manually scale things unless you are using it for a visual effect. Scale your models via the import options, which you’ll get into shortly, and leave the scaling to 1.0. This ends up being a lot more efficient.
The final panel is the Inspector panel – this gives access to all the publicly accessible properties of the selected object. This is an important concept to understand so take some time explaining what this means.
All elements in your game inherit from GameObject. Different Components, which derive from a component called MonoBehaviour, are attached to each GameObject. These Components determine how the GameObject will behave in your scene.
Each one of these Components is visible via the Inspector panel where you can tweak their properties. Components vary widely, and can range from anything from a simple script that you write, to a camera, physic properties, and more. Essentially, a Component provides you with a flexible way to build up your game elements in a modular fashion. It’s worth noting that all GameObjects have a Transform component – the Transform component determines where the GameObject lives in 3D space.
Note: If you’re familiar with iOS development think of your GameObject as an NSObject. Rather than inheriting functionality, you attach specialized classes to the object – each gives it different functionality but they are bundled together as one unit.
Below is a screenshot of the Inspector panel when the camera is selected.
The components here include: Transform (attached to all GameObjects), Camera, GUILayer, Flare Layer, and Audio Listener. Don’t worry about what they mean yet – I just wanted to show an example of how you can see components on an object and configure its settings.
Along with the panels, Unity exposes a host of functionality via the toolbar. The two items you’ll be most interested in are the Game Object and Component items.
The Game Object menu item provides you with a list of items you can add to the current scene. The submenu items you’ll be interested in are Create Empty and Create Other -> GUI Texture. Create Empty places a new (empty) GameObject onto the scene. Create Other -> GUI Texture creates a GameObject with the GUITexture component attached and the currently selected texture as its texture, or the default Unity logo if a texture is not selected.
At this point, you have a basic understanding of the Unity interface. You’ll get a chance to start playing around with it in the next section, where you’ll start creating your Unity scene!
In this section, you’ll walk through the process of importing an asset into Unity, discover how Unity handles assets, and quickly cover what Materials are and what role they play in Unity.
Looking at the list of features from the design section of this tutorial, you have a pretty good handle on what Assets you’ll require. Imagine your designer has created the assets for you, including the images and fonts necessary to create the main menu screen:
Here the user can quickly initiate a game and see their progress. Note that social networking is not implemented in this tutorial.
Your designer has also created some textures and 3D models for the main level, which will look like this:
He has delivered all of these assets as a zip file, which you can download here. After you unzip the file, you should see a directory of textures, fonts, images, and models like this:
Now let’s import a few of the assets into your project. On the Project panel in Unity, click on the Create button and select Folder. Create the structure as shown below:
Start with the GUI graphics you’lll be using in this tutorial. Drag all the files in the /NBNAssets/GUI folder into the /NothingButNet/GUI folder. These are the graphics that you will be using for your GUI, including the icon and splash screen.
Unity will automatically detect the type of asset you’re importing and set some default properties. In this case, Unity assumes that the .png files you’re importing will be used as 3D model textures and apply compression to them. This will result in a reduction in image quality when rendering them as GUI Textures, which you don’t want! :]
You’ll need to go through each image and set the type to GUI. To do this, select an item, navigate to the Inspector panel and select GUI option from the Texture type dropdown (as shown below).
Repeat the above for each of your images.
Next, import the textures for your models. Drag the .png files from the /NBNAssets/Textures folder into the /NothingButNet/Textures folder in Unity. Since these are textures for your 3D models, you can leave the default settings as they are.
Now import the fonts. Drag the .ttf files from the /NBNAssets/Fonts folder into the /NothingButNet/Fonts folder in Unity. These fonts come from www.dafont.com (http://www.dafont.com/score-board.font by Bou Fonts, and http://www.dafont.com/varsity.font by Unknown).
Finally, import the models. Drag the .fbx files from the /NBNAssets/Models folder into the /NothingButNet/Models folder in Unity.
Note: The models for this game were created in the open source (free) 3D creation tool Blender and exported as FBX. Unity provides extensive support for a wide array of media formats for audio, graphics, and 3D assets beyond just FBX files – for more information on the file formats supported by Unity, please refer to Unity’s importing guide.
After adding the models, you should check the textures are correctly associated with your models. To do this, click on each model and inspect in the Preview pane of the Inspect panel. If you click on the model and move the mouse around, you can rotate the model to inspect it from all sides.
If your models are grey, then it’s most likely that the link between the Material and Texture is broken. I’ll explain how this linking works and how you can fix it in the next section – materials and textures!
Materials and Textures
Models are associated with Materials. Materials are assigned a Shader (Shaders are small prgrams in the graphics pipeline that determine how the models vertices are positioned and how the model is rasterized to the 2D screen) which determines how Unity renders the image based on lighting, normal mapping, and pixel data. Some Shaders can be processor intensive, so the best idea here is to assign Shaders specifically for mobile to your Materials.
Open up the Materials folder found under Models. Here you can find the materials for each model. Select each Material in this list and change the Shader from Diffuse to Mobile/Diffuse.
If your texture hasn’t been associated with the material, then you’ll see a blank gray spot in the box where the image should be (there’s a “Select” button in the bottom right here). To associate the correct texture, you can click the Select button to choose a texture, or simply drag the texture onto this spot.
For the player, the material should look something like the following:
For the HoopTex Material, you’ll require transparency to be set. Select this material and choose the Transparent/VertexLit Shader.
There’s just a few things left to do in this section before you wrap things up. There is no standardized scaling between 3D modeling tools, so to get the models to a reasonable size, select each of them and update their scale factor from 0.01 to 1 as shown below:
Finally, open up the Player model and you’ll notice a few child elements, as below:
Some of these child elements will differ depending on what 3D modeling tool you are using. In Blender, the BPlayer and BPlayerSkeleton are the objects, the BPlayer (under BPlayerSkeleton) is the mesh data that describes the geometry of the player, and finally the items below that are animation frames, which will be described in further detail once you start wiring up your player!
Setting up the Scene
In this section you will visually setup the scene of your game. The goal here is to get some hands on experience working with the Unity scene environment, discover some more Components that Unity offers, and finally end up with a scene ready for your game.
Before you start visually designing your scene, consider the requirements from the design stage. You’ll have the camera facing side on to the court and the player, and positioned so that one of the hoops on the court can be seen.
Your goal is to arrange the scene so it looks somewhat like the following:
However, this is easier said than done! :]
This is your first chance to start playing around with the Scene, Camera, and Hierarchy panels in Unity. Perform the following steps:
- Select the Main Camera in the Hierarchy folder, and set X=6.5, Y=7, Z=14, and the Y-Rotation to -180.
- Drag a scene model into the Hierarchy panel, and set X=0, Y=0, and Z=0. You should see it appear in the Camera window!
- Drag a player model into the Hierarchy panel, and the Y-rotation to 90.
Now that you have some basic objects appearing, experiment moving the player around the scene using the Scene panel. Select the player, and drag it around the scene using the X, Y, and Z arrows that appear next to the player when it’s selected. You can also change the perspective of how you’re looking at the scene using the perspective switcher in the upper right of the scene panel.
At this point add the remaining objects – the basketball and the hoop. See if you can arrange them into roughly the right spot yourself using the Scene and Hierarchy panels – if you get stuck, you can always set their position back to the center (X=0, Y=0, Z=0).
While you’re playing around with this, you might notice that whatever you click on in Hierarchy is highlighted in the Scene. You can also easily zoom in on an object in the scene view – for example, try double clicking on the Player to center it.
If it isn’t centered the way you want it, use your mouse wheel to zoom in or out, drag the view in the window with the mouse, or hold down the Alt/Option key to rotate around and see things from another angle.
Note that none of these operations affect the actual position of objects, it’s just to help you get a better view.
Now that you have your scene roughly set up, time to configure the scoreboard!
Separating the Scoreboard from the Scene
Currently, the scoreboard is a child of the background, but you want it as a separate object. So in the Hierarchy view, drag it from a child of the scene into the root of the Hierarchy. The following dialog will appear – click Continue.
Note: GameObjects can have children and those children can have children, and so on and so forth. Children of a GameObject don’t directly inherit functionality of their parent (unless explicitly scripted), but rather use their parent’s scene space to position themselves. For instance, if the parent was moved along the x-axis, then all the children of the parent would also be moved e.g. if you held a basketball (your child) and walked forward, the basketball would move forward with you.
To make a child independent so that it doesn’t inherit the translation, orientation, and scale of its parent (also known as the object’s “pose”), then simply drag it out of its parent folder as you did here.
The reason you split out the Scoreboard like this was so you could add some 3D Text objects to it, to show the earned points and remaining time. This is not mandatory but rather an choice for aesthetics and organisation. Doing so helps (visually) de-couple it from the rest of the scene and gives you the choice of creating a prefab (which we will talk about later) that you would use if you were to create multiple levels.
The 3D Text object is — surprise! :] — an object that renders text in a 3D environment.
Add a 3D Text object to the scene by selecting the Menu GameObject -> Create Other -> 3D Text. This will place a new GameObject called New Text into your scene.
Rename this 3D Text object to Points and drag it into your Scoreboard object. Next, associate the scoreboard font with the 3D text by performing the following steps:
- Drag the Project\NothingButNet\Fonts\Scoreboard font to the Hierarchy\Scoreboard\Points\Text Mesh\Font property
In the inspector for the 3D Text, set the default text to “0000” and the alignment to right middle aligned. Then use the Scene panel to position the font on the right spot on the Scoreboard. Note you may have to rotate the text to get it to show up right – for me, my settings were X=0, Y=0, Z=2.8, Rotation X=270, Y=180, Z=0.
Now perform the same step for the Time text by duplicating the Points text using Cmd-D and positioning it slightly below. Name the duplicated object Time and set the default text to 00:00.
In the end you should have something that looks like the following:
Turn the Lights On
Have you noticed that the scene appears pretty dark? That’s because you haven’t added any lights to the scene, so let’s light it up!
Note: There are some considerations to be made when adding lighting to a scene. Adding lighting to a scene comes at a rendering cost. If you have done any Shader programming in the past, then you understand the additional effort to support the rendering of dynamic lighting. Each light requires each rendered object to calculate the final lighting effect depending on the Shader/Material being used, and has a high computational cost.
If at all possible, “bake” all the lighting details into the texture of the object before rendering. Baking is a way of rendering the textures with a static lighting effect applied, so that no additional computation is required to get the same visual effect. Also, use the scene’s ambient light to control the lighting intensity; this can be accessed via the Edit -> Render Settings panel.
In your simple scene, you will add a light. Select GameObject -> Create Other -> Directional Light to add a new directional light GameObject to your scene that will brighten everything up.
A full discussion about lighting is out of scope for this tutorial, but a directional light influences the whole scene depending on where you direct of the light by rotating the Directional Light GameObject. Select the light and use the move and rotate tools in the Scene panel to experiment moving it in different positions.
Now turn your focus (pun fully intended! :]) to the correct positioning of the camera. Camera positioning is not a science, but rather more of an art. Play the part of the director, and drag the camera into place using the movement and rotation tools in the Scene panel.
You can use the preview available in the Game panel directly below the Scene panel where you’re doing your scene building. As well, you can make use of the little preview window that pops up when the camera is selected in the Hierarchy view.
Next, in the you should update your Game screen dimensions to iPhone Wide 480×320, via the dropdown in the upper right of the Game panel. If you do not see this, go to Unity\Build Settings, and switch your platform to iOS. At this point, you should have a view similar to the one below:
Your scene is looking pretty good, isn’t it? Feel like a real director yet? :]
Unity Physics: Colliders and Bodies
It’s time to add Components to your Scene’s GameObjects so that they can react to each other!
Your goal is to have your objects react to each other when they collide. Luckily, Unity contains a fully-integrated physics engine and has packaged it up into a suite of Components that can easily dock onto your GameObjects.
Before you add ‘physics’ capabilities to your objects, you’ll need to first take a look into what ‘Physics’ means in Unity.
Click on the Components -> Physics menu (top toolbar) and have a quick look through the types of components readily available to you.
Colliders define the physical dimensions of your object, which can be independent of the visual shape of the object. In general, the colliders are ordered by complexity, and the more complex the object, the performance cost of using these objects rises.
Where possible, use Box/Sphere to encapsulate your objects, as these Colliders have the least computational load for your application. The other common Collider you’ll use frequently is the Mesh Collider. This uses the 3D model’s mesh to define the boundary of your object. In this case, the visual dimensions will equal the physical dimensions.
In addition to physically colliding with other objects, a Collider can be set up as a trigger that can detect collisions (so you can make something happen programmatically), but not actually cause any collision responses. This will be useful so you can detect when the ball goes through the basketball net.
In order for objects to react, each object must have some form of body in addition to a collider. This is done by either adding a Rigidbody or CharacterController to the GameObject.
The best way to get comfortable with Physics is to play around – let’s make that basketball bounce!
Bounce that Basketball!
Select the basketball, and add a Rigidbody onto it by selecting Component > Physics > Rigidbody. Then hit the Play button in the upper center of Unity to preview the gameplay – you’ll see the basketball fall below the floor.
If your basketball “warps” to the middle of the scene when you click play, select the basketball and unclick the Animation checkbox in the properties and try again. It should stay in the right spot now.
But it wouldn’t be much of a game if the ball was allowed to fly out of the scene! :] You’ll need to create a set of boundaries that will constrains the ball to the playing area.
To do this, select the scene.Wall object and select Component > Physics > Mesh Collider. Repeat for the scene.Ground and scene.Background objects. Then select the scene.court object and select Component > Physics > Box Collider.
If you play the scene again, you’ll see that it still falls through the floor. This is because you still haven’t set up a collider for the basketball!
So select the basketball and go to Component > Physics > Sphere Collider to set up a sphere collider for your basketball. It will default to the right size, but you can change the radius if you want in the Inspector’s Sphere Collider section.
Along with the ball reacting to the environment, you’ll also want it to bounce when it collides with an object. To do this, you’ll need to assign a special type of Material that Unity provides called a Physic Material.
Where Materials affect how objects look, Physic Materials determine how the object behaves when a collision occurs. This is associated with the Material property of the GameObjects Collider component.
The following image shows the properties of the Rigidbody attached to the basketball:
On the Project panel, select the Create dropdown menu and then select Physic Material to create a Physic Material , and name it BallPhyMat.
Now set the properties of the Physic Material as shown below. Details on the function of each of the properties shown below is out of scope for this tutorial, but further information can be found at http://docs.unity3d.com/Documentation/ScriptReference/PhysicMaterial.html.
In order to allow the ball to bounce, friction is set fairly low.
To associate the newly created Physic Material to the basketball, select the Physic Material you just created and drag it to the to the basketball’s Collider material property.
Click the play button again, and this time it falls to the floor and bounces, w00t! :]
As for the hoop, you want it to react to the ball as well as detect when the ball goes through the net. Add a Mesh Collider to the hoop mesh (hoop.LeftHoop).
Also, you want to set up a sensor or “trigger” to detect when the ball goes through the hoop. To do this, add a Box Collider to hoop.LeftHoop_001, but shorten the box and position it so it’s just below the net (you can do this by tweaking the values in the Inspector – I changed Center Z to -1.4 and Size Z to 0.2). Also, click the checkbox to set the trigger property to true.
Note: to visually resize colliders using the mouse, select the collider’s object and hold down Shift. This will show the handles of the collider, allowing you to resize it using the mouse.
Okay! That takes care of the ball — time to take a look at the Player object! :]
Meeting the Team
In this game, we want the player to bounce the ball and for the ball to not roll through him. Stopping the ball rolling through the Player is easy enough; go ahead and add a Capsule Collider to the player GameObject.
You’ll then need to position and size the capsule – I changed the height to 3.8 and the Center Y to 1.8.
Note: Colliders are shown in the Scene panel in a green outline — unless they are Mesh Colliders , in which case it’s the mesh that shows the collision boundaries.
The approach used to bounce the ball requires that the game can detect when the ball collides with the player’s hand. When this occurs, you will push the ball back down to the ground, just like it happens in real life! To attach the collider at the correct position, you’ll drill down to the player’s skeleton and add the collider to the hand which will be used to bounce the ball.
The above screenshot shows you the children of the player GameObject. Where do these children come from? Good question! :]
These children form the skeleton built to animate the player – the parent is the pelvis which also has the Skeleton Mesh Renderer component attached to it, which is responsible for rendering the mesh,. The children are the bones of the skeleton which were built in Blender. ArmIK_L, ArmIK_R, LegIK_L, LegIK_R are just handles used in Blender and have no function in your app.
Now add a Box Collider to player\BPlayerSkeleton\Pelvis\Hip\Spine\Shoulder_R\UpperArm_R\LowerArm_R\Hand_R and resize the Collider similar to what is shown below, and set the trigger flag to true.
Prefabs — and how to Take Advantage of Them
This section is just an optional note that may be useful for you later – feel free to skip if you need a break! :]
A game app normally consists of a lot of objects that are identical but are used multiple times. For instance, you may have created a city using the same building over and over again. An efficient way to do this is to create a master template which you can reuse over and over again. As well, it gives you the advantage of being able to update all of the objects by simply updating the template.
Unity provides the ability to do this through the use of Prefabs. Prefabs allow you to create one master copy of an object and create multiple identical copies of it. However, even if you don’t want to create multiple copies of your object, it still provides an efficient way of creating and managing a setup for each of your game objects.
To create a Prefab, you can either just drag over an object from your Hierarchy panel to your Project panel, or you can explicitly create a Prefab via the Project dropdown and then drag the object(s) from your Hierarchy panel into this object.
Now each time you want to create another object from this template, you just need to drag the Prefab over to the scene. Very easy — and very useful! :]
Note: to make an update to your Prefab, just grab any Prefab of the type you’re interested in, make your updates, and then select the Game Object -> Apply Changes To Prefab option from the toolbar menu. The changes will automagicall propagate to all associated objects!
Where To Go From Here?
Congratulations, you made it! You’ve gotten through the hardest part – getting used to the Unity GUI as a complete beginner – from here on out it will be smooth sailing :]
Here is a sample project where we have left it off in the tutorial so far. To open it in Unity, go to File\Open Project, click Open Other, and browse to the folder. Note that the scene won’t load by default – to open it, select Scenes\GameScene.
So far, you have explored how GameObjects can contain children and their children live in their space (in terms of pose). You looked at Lighting concepts and Colliders , and associated Physics concepts with your objects. You also added a Physic Material to the ball to influence how it reacts when a collision occurs, as well as seeing how Colliders can be used as triggers or by the physics engine.
And that’s it for the first part! :] In the next section of this tutorial, you’ll bring your scene to life with interactivity and animation. That will happen when you’re introduced to Scripting. Until next time!
This is a tutorial by Joshua Newnham, the founder of We Make Play, an independent studio crafting creative digital play for emerging platforms.