Beginning Unity 3D for iOS: Part 1/3

Christine Abernathy Christine Abernathy

This post is also available in: Chinese (Simplified)

Learn how to use Unity to make a simple 3D iOS game!

Learn how to use Unity to make a simple 3D iOS game!

Unity is one of the most popular game engines these days. And for good reason – Unity has a powerful visual editor that makes it very easy to get started, a ton of power and functionality, a great community, attractive pricing, and more!

If you’ve been eager to try out Unity for yourself, look no further than this tutorial! In this tutorial you’ll learn how to create a simple iOS game with Unity – and no prior experience is required! :]

The simple game you’ll create in this tutorial will challenge the player to get to a finish line within a certain time limit while avoiding obstacles along the way.

Along YOUR way, you will be introduced to the Unity development environment and workflow, and learn (or review) the basic concepts of game design.

The tutorial will be split into three parts:

In Part 1, you’ll learn the basics of using Unity by creating a game with a simple player control mechanism. You’ll also learn how to deploy your project on iOS.

In Part 2, you’ll learn how to enhance the player’s movements using pre-built controller objects and some scripts found in the standard packages, how to debug using Unity Remote, and how to customize the scene.

In Part 3, you’ll add gameplay to your project and build on game design concepts that include adding prefabs, timers, menus and sounds to enrich the game experience.

Ready to add a powerful new framework to your skillset? Keep reading on! :]

Getting Started

As you move through this tutorial series, you’ll start to become familiar with the Unity development workflow, which has four basic components:

  1. Assembling your game scene in the Unity Editor.
  2. Scripting using the MonoDevelop Editor.
  3. Remote debugging with Unity Remote.
  4. Publishing to your iOS device through the Unity Editor.

In this first part of the tutorial, you’ll install Unity, learn the basics of the Editor interface, and create a project that introduces you to the basic game concepts.

By the end of Part 1, your game will have a player that is able to move via touch triggers. You’ll also test your project in the Unity Editor and with an iOS device.

This tutorial uses Unity version 4 – so go ahead and download Unity if you don’t have it already.

Unity’s doffers a free 30-day trial of the full version of Unity Pro. This version of Unity will allow you to develop games and build them to run on iOS. Although Unity is available for both Mac and Windows, this tutorial is written based on the Mac environment.

Note: The Unity software package is a fairly hefty one at close to 1GB and, depending on your Internet connection, it might take a while to download. So download the file in advance if you want to get going immediately. :]

Create the Project

Once you’ve downloaded Unity and installed it, launch the Unity application. If this is your first time launching Unity, you will be prompted to activate your copy. Select the option to activate the free 30-day trial of Unity Pro, as shown in the screenshot below:

Unity License Activation

Then you will need to create a Unity account if you do not have one, confirm your e-mail address, and login to your account via the Unity app.

Once you login, you’ll be asked to answer a few questions. You can skip them if you scroll to the very bottom of the list and tap “Not Right Now.” :] And then, finally, you can start using Unity.

At this point you should be presented with the Unity interface with a default project already in place – something like the following:

Unity Starter Project

Discard that project and create a fresh project by selecting File\New Project from the menu. You’ll be presented with the Project Wizard:

Project Wizard

In the Project Wizard, click Set and navigate to the folder where you wish to save your project. Enter DashAndZag for the project name and click Save, then Create Project. (You will be asked whether you want to save the previously open default project, but you can opt not to do so, unless of course you want to save it for some reason…)

Note: The Project Wizard includes some standard packages you can import during the initial project creation. Ignore this for now. You’ll import any packages you need for this tutorial later on.

Unity will close the current project and re-launch with your new project:

Initial Project

Ah, a fresh canvas! But what are all these controls, windows and tabs? Where to start?

Getting to Know UI…

It’s worth taking some time to get real cozy with the Unity Editor interface, so take a look around. The first stop on your tour is the Editor Layout tab in the upper-right corner. Change the view to Wide mode:

Change Layout

Here’s a breakdown of what you see, with the various sections highlighted:

Unity Editor

  • Project View: Your Unity project contains an Assets folder whose contents are shown in this section. This is where the scripts, scenes, prefabs and other Unity objects that you create show up.
  • Hierarchy View: This contains the GameObjects that are in the current scene. Every object that shows up in a Unity game is known as a GameObject. These could be simple objects that you create from the GameObject menu or assets you import. Your initial project will contain one GameObject: the Main Camera.
  • Toolbar: The toolbar allows you to manipulate objects in the Scene View or Game View, to control how your Editor views are displayed and to control the game preview in the Editor.
  • Scene View: This view is where you position your GameObjects to set up your game. The Scene View contains a Scene Gizmo (the thing in the top-right corner with the marked axes) that displays the scene camera’s current orientation.
  • Game View: This is the view of your game from the camera(s) in your game. You’ll be brought to the Game View when you hit the Play button in the toolbar. Alternatively, you can switch between the Game and Scene views using the tabs at the top of the window.
  • Inspector: This provides further details about a selected GameObject. You can then modify the object’s properties such as its size or position, or attach scripts to modify the GameObject’s behavior.

You’ll want to be very comfortable using the toolbar transform tools to position GameObjects and navigate around in the Scene View. So let’s dive into that next.

Getting a Hand

The Hand Tool allows you to manipulate your view of the scene.

Hand Tool

The best way to understand the Hand Tool’s use is to imagine yourself dropped into the 3D scene with many GameObjects. Some objects in front of you are visible, while others that are behind you are not.

You may wish to step back in the scene (zoom out) to see more of the view, move to the left or right to see other objects, or swivel and pan around to see what’s behind you. The Hand Tool can do this for you.

As you start to add more GameObjects, you’ll find yourself using this tool more and more to establish your view in the scene before positioning GameObjects.

To see the Hand Tool in action, first select it (left-most choice on the toolbar), then select the Main Camera from the Hierarchy View (just so you have something to look at in the Scene View). You can then drag the canvas to move around the scene.

To zoom, you can use your mouse wheel or hold down Control and drag. You can rotate by holding down option and dragging. If you want to reset your view at any time, you can click on one of the axes on the Scene Gizmo in the upper right.

Hand Tool

Play around with the hand tool a bit and get comfortable with moving around and using the Control and Option combinations to zoom/rotate.

You’ll be switching between the hand tool and other tools a lot, so it helps to remember its shortcut keys. By default, the keys are bound to the keys on the upper left of your keyboard – Q, W, E, and R for Hand, Move, Rotate, and Scale, respectively.

Note: The Hand Tool does not move objects. It only alters your view of the scene, so it may appear as if the objects are moving. Practice moving around the scene using the various Hand Tool options.

Move It Or Lose It

With the Move Tool, you can move GameObjects in 3D space.

Move Tool

Select the Main Camera (double-click it in the Hierarchy View if you don’t see it in the Scene View) and click on the Move Tool. You should see a gizmo around the Main Camera with arrows representing the three axes. These point to where you can move the object:

Move Gizmo

The red arrow represents the x-axis, the green arrow the y-axis, and the blue the z-axis. You can translate or move a GameObject by first selecting the object, left-clicking, and then dragging inside the gizmo (the cube portion).

Select the Main Camera and move it around. Take a look at the Inspector’s transform component. The Position section has x, y, and z values representing the GameObject’s position. As you move the object around, notice that these values change.

Transform Component in Unity

You can change a GameObject’s transform position using either the Move Tool or by typing the position you want directly into these fields.

If you wish to move a GameObject in only one direction, select the relevant axis in the gizmo, left-click and drag that axis. Test this with the Main Camera object by moving in only the x direction and checking that only the x-position value changes in the Inspector. Repeat the same test with the y and z axes.

Inspector after X axis movement

At this point you know how to move your personal view of the scene around, as well as how to move objects around. So far so good!

You Spin Me Right Round

The Rotate Tool allows you to rotate GameObjects in 3D space.

Rotate Tool

To understand the Rotate Tool and how to use it, it’s useful to discuss the Scene Gizmo in more detail. The Scene Gizmo is found on the top-right of the Scene View and has different modes for different views.

One mode (shown in the below right image) is the free-form view that enables you to view your scene in a 3D perspective. This is useful if you want to get a better representation of what your game looks like in 3D space.

You can click on the text under the gizmo to switch to an isometric view (shown in the below left image). This mode is useful in visualizing a GameObject when it’s being rotated.

Scene Gizmo - Perspective View

Another mode is the x-axis view, which enables you to view your scene as if you’re looking down the x-axis. This is useful if you want to move a GameObject along either the y- or z-axis while keeping the x-axis unchanged:

Scene Gizmo - X View

In a similar fashion, you have the y- and z-axis view modes to enable the view of the scene from those respective axes:

Scene Gizmo - Y View

Scene Gizmo - Z View

Select the Main Camera. Switch to the free-form perspective mode by right-clicking on the gizmo and selecting Free.

Switch to Free Form View

Then click on the text below the gizmo to switch between the isometric and perspective modes. Click on the x-, y-, and z-axis modes in turn to see how the Scene Gizmo and Scene View change.

Select the free-form view once more to test out rotation. With the Main Camera still selected, click the Rotate Tool. You should see a gizmo around the Main Camera containing circles with colors representing the three rotation axes:

Rotate Gizmo

Left-click in the center of the Main Camera and use your mouse to drag-rotate it around. Note that the Inspector’s Transform\Rotation properties change as you rotate the object. Note that you can manually edit these values in the Inspector if you’d like.

By clicking in the center of the Main Camera during rotation, you are doing a free-form rotation around all axes. You can also rotate the GameObject around one axis by clicking on one of the colored circles representing that axis. For example, to rotate only around the x-axis, click the red circle to select it, then hold and drag to rotate the object. Repeat the same process to rotate around just the y or z axis.

It All Comes Down to Point of View

Another key concept worth learning at this point is the difference between the local and global (or world) view.

Toolbar - Global

Toolbar - Local

Reset the Main Camera’s rotation to 0,0,0 through the Inspector\Transform\Rotation fields. Click the button so the toolbar says “Local”. Then select the Move Tool so you can see the Scene Gizmo:

Global and Local Aligned

Notice that the Scene Gizmo and the Main Camera’s Gizmo line up, in the sense that the x-axes point in the same direction, as do the y- and z-axes. Now rotate the Main Camera around on the z-axis using the Inspector by setting the Transform\Rotation value to 0,0,-20.

Global and Local Alignment after Rotation.

Notice that the Main Camera’s Gizmo is now rotated around the z-axis – this represents the axis of the object in its local coordinates. This is different compared to the Scene Gizmo, which shows the global space orientation. Switch to Global view to see the difference.

Later in the tutorial, you’ll learn about moving GameObjects and find that it matters which space (world or local) you specify for the movement to use.

Taking a look at the rotated Main Camera, if you were to now move it in the x-direction based on its local space view, it would end up in a different place than if you were to move it in the x-direction based on the global space orientation. Keep that nugget tucked in your mind for later use!

Before you move on, reset the rotation to 0,0,0 to get back to a clean slate.

Scale Tool

The Scale Tool allows you to, you guessed it, scale GameObjects up or down in size.

Using the Scale Tool

As with the other GameObject manipulation tools, you can make your changes along only one of the three axes, and you have the choice of modifying the Inspector\Transform component instead of using the tool.

Select the Main Camera and note that the Scale Gizmo consists of cube handles at the end of each axis and one at the center.

To scale freely across all axes, select the cube at the center of the object and left-click, then move up to make the GameObject bigger and move down to make it smaller. Take a look at the Inspector\Transform\Scale properties. You should see the numbers go up or down as you grow or shrink the object.

Scale Component in Unity

Test scaling along the x-axis by selecting the red gizmo handle for the x-axis, and holding and then moving the handle outward. Verify using the Inspector that the Transform\Scale x-value is the only one that changes. Try this with the y and z axes as well.

Once you’re done playing around with the controls, reset the Main Camera to the following settings using the Inspector\Transform section:

  • Position: 0,1,-10
  • Rotation: 0,0,0
  • Scale: 1,1,1

Your Transform menu should look like this:

After transform properties reset.

You will learn about the other Editor interface components as you walk through the tutorial. This includes previewing a game using the Play button and using the Unity debugger.

Lonely No More: Adding GameObjects

Now that you’ve run through the basic concepts, you’re ready to begin adding GameObjects to keep the camera company – it’s been pretty lonely all by itself :]

Right now the camera is looking out on a very desolate world. Never fear – get ready to add a cube GameObject that represents the player, as well as a plane GameObject that represents the floor the player will move upon.

When you’re designing a game with Unity, a best practice is to first develop the gameplay without any fancy assets that represent the player. That way, you can concentrate on optimizing gameplay and player movements without being distracted by graphics.

Another point to note is that Unity is a very good game engine, but you don’t want to use it to create graphic assets. There are many tools out there that are wonderful in the graphics department and Unity is adept at importing assets from a wide range of tools.

Often, the typical division of game development labor is that the game developer works on the gameplay using Unity while the graphics designer creates assets in parallel using their favorite graphics tool. The two converge down the line when it makes sense to bring in the graphical assets to polish up the game.

Now that you’ve got that to think about, let’s get shaking! Add the floor GameObject, represented by a plane, by selecting Game Object\Create Other\Plane.

The new plane GameObject should appear in the Hierarchy View. Select the plane in the Hierarchy View and set Transform\Position to 0,0,0 using the Inspector. Also use the Inspector to scale it up to 50,1,50. Your scene should look something like this:

Adding plane GameObject.

Next you’ll add the player GameObject, which in your game will be represented by a cube. That’s right, the Heroic Cube!

Select Game Object\Create Other\Cube, and the new cube GameObject should appear in the Hierarchy View. Select the cube in the Hierarchy View and set the Transform\Position to 0,0,0 using the Inspector. Your scene should look like this:

Adding Cube GameObject.

Click on the Move Tool, then click the y-axis in the Scene Gizmo to constrain the object’s move to only the y-axis. Move the Heroic Cube up a little so it’s above the plane (floor). You can also set the transform position to 0,1,0 to move the Cube up a little.

Now comes an exciting moment – click the Play button on the Unity Editor toolbar (at the top) to preview your game thus far:

Play game.

You’re now testing your game using the Unity Editor. The Editor should switch to the Game View and you should see something like this:

Initial game view.

What you’re seeing is a view of the game through the Main Camera in your scene. Your player, the Heroic Cube, is shown in the distance, above the floor – alone in the world, but bravely present!

There’s not much going on in the game because you haven’t added any components to modify the player’s behavior. It’s also a little dark in this scene. You can take care of the latter issue first by adding a light source to your scene.

Stop the game preview by clicking on the Play button again. Back in the Scene View, add a light source. Select Game Object\Create Other\Point Light. As usual, move the light to the origin before making further adjustments to its position. Set the transform position to 0,0,0 using the Inspector.

Now adjust the light’s height and brightness so you can see more of the scene. Here’s a hint: use the Move Tool and constrain movement along the y-axis only.

To adjust the brightness, modify the Range and Intensity settings in the Light component. Make use of the Hand Tool to swivel around if you need to get a better view of the scene.

A good way to see if you have enough light is to switch to the Game View using the Game tab (rather than hitting the Play button). Go back and forth until it looks like you can see your player:

Adding point light GameObject.

After you’ve made your adjustments, hit the Play button again to verify your changes. Your view should be similar to the following when you switch to the Game View:

Game after light source added.

Congrats, you’ve added all the GameObjects you need for this stage of the tutorial! Remember, as a good practice you are focusing on gameplay first, then adding graphics later.

Since you’ve done something meaningful, go ahead and save your work as a scene in the project. A project can be made up of one or more scenes. You can think of a scene as the equivalent of a level in a game.

In this tutorial, you’ll represent each part of the tutorial as a scene. This is an artificial concept of a game level, but it allows you to reuse assets from one scene in the next.

To save the scene, select File\Save Scene and in the Save Scene dialog, name your scene Level_1. Your Project View should update with the scene you’ve just created.

Level 1

Get Moving: Event Functions

The game is currently way too static! It’s in dire need of movement to make it come alive.

You can add movement by creating your own scripts or using pre-packaged scripts that you attach to the relevant GameObject to perform an action. For example, in Part 1 of this tutorial, you’ll create a script that moves the player when touched. The script you create needs to respond to touch events to change the Heroic Cube’s position and rotation.

Unity supports these languages for scripting: JavaScript, C#, and Boo. In this tutorial you’ll be using JavaScript. Unity’s scripting language includes pre-defined event functions that you can use to help define the GameObject’s behavior.

  • The event function that you’ll use the most is the Update() function. If you define this function in your script, it will be called once per frame. Your game display is drawn once per frame and the Update function will therefore be responsible for the display during a particular frame.

    A game runs at a certain amount of frames per second and one thing to keep in mind is that this rate may vary depending on the Platform on which the game is being run, and on how tied up the OS resources are by other applications. This means you shouldn’t do anything very time intensive here, and you can’t assume that it is called at any particular rate.

  • Another pre-defined event function, FixedUpdate(), is called at a fixed rate independent of the frame rate. If your script defines this method it will be called at a fixed interval (in comparison to the Update method which can vary quite a bit from call to call).

    You’ll want to process any physics-related work inside of a FixedUpdate() function, since physics work is very time sensitive. For example, you may have a GameObject that uses physics, such as RigidBody (you’ll learn more about this later). When this object collides with another object you may want to calculate the force to apply to the object, and you should do it in a FixedUpdate() function.

    For operations like changing an object’s transform position or rotation, it’s perfectly fine to do this inside of an Update() function.

  • A third useful function is Start(), called before the first frame update happens. You’ll typically put initialization operations here.
  • Finally, the Awake() function is called when the game begins. It’s another good place to put initialization code.

The Right Touch

Let’s try this out. Create a new script by selecting Assets\Create\Javascript. A new script with the default name NewBehaviorScript should show up in your Project View. Click inside the script’s name in the Project View and rename it to MoveSimple.

Double-click on the script to open it. It should open in the bundled MonoDevelop Unity Editor and should contain the following code:

#pragma strict
 
function Start () {
 
}
 
function Update () {
 
}

The Start() and Update() functions have been stubbed out for you, as they are commonly used event functions. You won’t be needing the Start() function, so remove it. Add the following variables that you’ll use to control the Heroic Cube’s movement and rotation speed below the #pragma line:

var speed : float = 3.0;
var rotateSpeed : float = 10.0;

Replace the empty Update() function with the following:

function Update () {
    // Detect mouse left clicks
    if (Input.GetMouseButtonDown(0)) {
        // Check if the GameObject is clicked by casting a
        // Ray from the main camera to the touched position.
        var ray : Ray = Camera.main.ScreenPointToRay 
                            (Input.mousePosition);
        var hit : RaycastHit;
        // Cast a ray of distance 100, and check if this
        // collider is hit.
        if (collider.Raycast (ray, hit, 100.0)) {
            // Log a debug message
            Debug.Log("Moving the target");
            // Move the target forward
            transform.Translate(Vector3.forward * speed);       
            // Rotate the target along the y-axis
            transform.Rotate(Vector3.up * rotateSpeed);
        } else {
            // Clear the debug message
            Debug.Log("");
        }
    }
}

Save your changes.

This code first looks for mouse click events, specifically from the left mouse button. A parameter of “0″ signifies a left-click, “1″ a right-click and “2″ a middle-click when used with the GetMouseButtonDown function. If a click is detected, then the code constructs a ray (think of a laser pointer) from the Main Camera to the mouse click position.

The collider.Raycast() function detects if the collider attached to this script is hit by the ray. If the collider is hit, the collider.Raycast() call returns true. The function call takes in three arguments:

  1. The ray you constructed.
  2. A RaycastHit object, which will contain more details if the collider is hit.
  3. A ray length argument.

Assuming a true result, the follow-on code then nudges the player forward based on the speed variable, as well as rotates the player based on the rotateSpeed variable. The transform.Translate() function moves the GameObject transform in the direction and distance specified by its Vector3 input.

Vector3 is a 3D vector representation of an object that has direction and a length or magnitude. The vector can be broken down into x, y and z components.

In the code, your Heroic Cube is moved in the forward direction at a distance multiplier calculated based on the speed variable. Vector3.forward is the same as Vector3(0,0,1) and a speed multiplier of 3 will move the Cube by Vector3(0,0,3).

The direction in which the player moves is relative to the player’s local space. To get a sense of this direction, select the Cube, then the Move Tool and view the z-axis direction. That’s the direction in which the player will move.

The transform.Rotate() function rotates the GameObject transform based on an angle specified by the Vector3 input. Euler angles are used to describe the orientation of a GameObject. In the case of a rotation, the object will be moved Euler angles z degrees around the z-axis, Euler angles x degrees around the x-axis, and finally Euler angles y degrees around the y-axis.

In the code above, the player is being rotated using Vector3.up or Vector(0,1,0), which represents movement around the y-axis. The rotation angle is multiplied by rotateSpeed. The rotation is relative to the player’s local space. So your Heroic Cube will rotate around its y-axis, which, as you know, could differ from the global y-axis.

Note: A real game would never control a player using these types of movements. They are used here simply to illustrate the basic concepts involved in moving GameObjects and will be replaced with more realistic movements in the upcoming parts of the tutorial.

The code contains two Debug.Log() statements. The log output is printed in the Unity console when the game is running. You can see the last log output at the bottom of the Unity Editor. You can also open up the console by selecting Window\Console to see previous log output, as well as clear the logging.

You’ll want to keep an eye on log output at the bottom of the Unity Editor, as that’s where any script errors you have are displayed.

Now that you’ve defined a behavior via code, you can assign it to a GameObject. Select the Cube in the Hierarchy View, then select Component\Scripts\Move Simple. This step is called adding a script behavior to a GameObject and you are simply selecting the script (named MoveSimple) that you already created.

After Move Script added.

Notice that the Inspector now contains a Move Simple script section. The public variables you defined in code, speed and rotateSpeed, are visible in the Inspector View. You can now modify these public variables for just the attached GameObjects without changing the underlying script.

This means if you had two players in the scene with the MoveSimple script attached to them, you could make one player move faster than the other by increasing the speed value via the Inspector\Move Simple\Speed field.

Click Play to preview the game. Touch the player one tap at a time and pay attention to the changes in the transform position and rotation properties in the Inspector.

Game view and transform position changes.

Notice that the transform position that started at 0,1,0 has changed to 0,1,3 – in other words, there’s been a translation movement in the z direction of 3 due to the speed multiplier. The rotation has also changed from 1,1,1 to approximately 1,10,1, which closely matches the rotateSpeed multiplier.

While the game is running, you can change the speed and rotate speed variables in the Inspector. Increase the speed and watch the transform position after clicking on the player.

Stop the game and notice that the speed and rotate speed variables are reset to their original values. Any changes you make while playing the game are temporary. This allows you to tinker around with various settings and come back to the original settings when you’ve completed your preview. If you then want to make lasting changes, you can do so before testing the game again.

Note that as you play the game, the console logs the correct debug statement, depending on whether or not the player is clicked.

Get It All On Camera

You’ll likely have noticed that as you move the Heroic Cube, it moves further and further away from the camera – not a good feeling. Like a well-meaning parent with an ambitious toddler, you’ll modify your game to have the Main Camera track the player at a fixed position from behind. This is typical modus operandi for third-person shooter games.

Select Assets\Import Package\Scripts and in the Items to Import section, choose only the SmoothFollow script and click Import:

Importing the Smooth Follow script.

Note: If you don’t get the import selection dialog when you select Assets\Import Package\Scripts, then try quitting Unity and restarting. That worked for me. :]

A new Standard Assets folder should show up in your Project View. If you navigate through its subfolders you should eventually see a SmoothFollow script. Double-click the script to open it in MonoDevelop so you can look through the key portions of code.

var target : Transform;

The above represents the public variable for the target being tracked. The target’s transform info is used to set the follower’s (or Main Camera’s) position and rotation.

The follower’s position and rotation are set in LateUpdate(), another pre-defined event function. This function is called just after the Update() function completes, and is typically where you would put code that has a dependency on operations that happen in Update().

Once the Heroic Cube’s position and rotation are changed in the Update() defined in the MoveSimple script, the camera can update its own position and rotation in the LateUpdate() of the SmoothFollow script.

..
var wantedRotationAngle = target.eulerAngles.y; // 1
var currentRotationAngle = transform.eulerAngles.y;
..
currentRotationAngle = Mathf.LerpAngle (currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
..
var currentRotation = Quaternion.Euler (0, currentRotationAngle, 0);
 
..
transform.position = target.position; // 2
transform.position -= currentRotation * Vector3.forward * distance;
transform.position.y = currentHeight;
..
transform.LookAt (target); // 3
..

Here are the key points for the above code sections:

  1. Find the angle to which the follower needs to rotate, to match the target rotation. The rotation is around the y-axis.
  2. Move the follower behind the target by an offset corresponding to the distance variable. Also rotate the follower around the y-axis using the results from #1. Finally, make sure that the follower ends up at a fixed height above the target.
  3. Ensure that the follower is always facing the target.

Now attach this script to the Main Camera. Select the Main Camera in the Hierarchy View, then select Component\Camera Control\Smooth Follow:

Smooth Follow script added.

Verify that a new section for Smooth Follow is added to the Main Camera’s Inspector.

Note that the Target variable is unassigned at this point and has None next to it. You’ll want to assign the Cube GameObject to this input. While the Main Camera is still selected and the Smooth Follow script visible in the Inspector, drag the Cube GameObject from the Hierarchy View to the Target variable. Alternatively, you can tap the little circle with a dot in the center next to the Target value to get a list of objects from which to select.

Smooth Follow script target assigned.

The Target variable should now be linked to Cube (the player).

Click the Play button. You should immediately see a change in the view, as you’re now looking down at the player from a given height. Click on the player to move it, and watch how the camera tracks the player. Pay attention to the Main Camera’s transform info in the Inspector and observe it change as the Heroic Cube moves.

Stop the game, and save the scene before moving on to the next step.

Deploying on iOS

If you’re like me, you can’t wait to see how this works on an iOS device. :] The good news is that the trial version of Unity Pro allows you to test your project on iOS!

It’s a best practice to test your Unity projects on an actual device (i.e. not the Simulator). You don’t want to limit your testing to just the Simulator, even though you can do that. Since game development relies so much on the underlying hardware, you want to test on a real device as soon as you can to find any performance issues early.

To deploy to an iOS device, you need to be a registered Apple developer with device deployment capabilities. If you haven’t already, go ahead and fork over the $99 – we’ll be right here waiting for you. :]

Unity can build your game as an Xcode project that you can deploy to an iOS device. To set this up, select File\Build Settings:

Build Settings.

Select the iOS platform and click Switch Platform. Then click on the Player Settings button found at the bottom of the Build Settings dialog. Unity Editor’s Inspector should now display Player Settings that you can customize for your iOS deployment. Make the following changes:

Resolution and Presentation

  • Default Orientation: Landscape Left

iOS Resolution and Presentation settings.

Other Settings

  • Bundle Identifier: the Bundle Identifier needed so that your app can be properly built on your device.
  • SDK Version: Device SDK
  • Target iOS Version: 4.3

iOS Other Settings.

Go back to the Build Settings dialog. Add the scenes that will be part of the iOS build in the Scenes In Build section. Since you only have one scene in your project, this is a no-brainer. Add the Level_1 scene by clicking the Add Current button.

Adding scene to Build Settings.

Click the Build button to initiate the build process. You’ll be asked to specify a location to save the Xcode project. Navigate to where you want to save your Xcode project, enter DashAndZag in the Save As field, and select Save.

Unity will now build the project and open the folder that contains the Xcode version. The project will have the name Unity-iPhone.xcodeproj.

Open the project using Xcode, make sure that the scheme is set to Unity-iPhone, select your device, and build the project.

Xcode project scheme.

Run the app. You should first see a splash screen with the default Unity logo. Then, your game should come up:

Game running on iOS.

Touch the Heroic Cube and watch it move around. You’ve just built and deployed your first Unity project on iOS!

One Finger to Rule Them All

But wait, you’re not done yet!

If you play the game a bit longer, you’ll notice something odd. You can move the Cube by touching it with one finger. However, the Cube will also move when you use two fingers placed at an equal distance from it. What’s going on?

Recall this line of code from your MoveSimple script:

var ray : Ray = Camera.main.ScreenPointToRay 
                    (Input.mousePosition);

This casts a ray from the camera to the touch point. The touch point is represented by Input.mousePosition. When running on an iOS device, Input.mousePosition is calculated as an average position of all current touches. Placing your fingers so that the average falls on the player makes the player move!

You should fix this to avoid confusing the user. You can use touch-related functions available in Unity to detect touch events and find the position of a touch more accurately.

Open your MoveSimple script. Add a flag at the top (where the other variables are) that will indicate that you can use touch input:

private var isTouchDevice : boolean = false;

You’re doing this so you can test on both iOS and the Unity Editor. If you’re only going to test on iOS, then you can bypass the touch check logic and simply use the touch-related functions.

Next add an Awake() function that will perform a runtime check to detect if the game is running in an iOS environment. The Awake() function is called only once, when the game is loaded:

function Awake() {
    if (Application.platform == RuntimePlatform.IPhonePlayer) 
        isTouchDevice = true; 
    else
        isTouchDevice = false; 
}

Application.platform returns the platform on which the game is running. RuntimePlatform.IPhonePlayer indicates that the game is running on iOS.

Finally, modify your Update() function as follows to handle touch input:

function Update () {
 
    var clickDetected : boolean;
    var touchPosition : Vector3;
 
    // Detect click and calculate touch position
    if (isTouchDevice) {
        clickDetected = (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began);
        touchPosition = Input.GetTouch(0).position;
    } else {
        clickDetected = (Input.GetMouseButtonDown(0));
        touchPosition = Input.mousePosition;
    }
 
    // Detect clicks
    if (clickDetected) {        
        // Check if the GameObject is clicked by casting a
        // Ray from the main camera to the touched position.
        var ray : Ray = Camera.main.ScreenPointToRay 
                            (touchPosition);
        var hit : RaycastHit;
         ...

Save your changes.

You are using two new local variables, clickDetected and touchPosition, to detect clicks and save the click position. If running on iOS, you detect the click by checking that a touch has just begun. Then you calculate the click position based on the position of the first touch. If you’re not running on iOS, the logic is the same as before.

Before rebuilding the project, close the Xcode project. Now, rebuild in Unity from the Build Settings dialog. If presented with a warning about the Build folder already existing, select Replace.

Build warning.

Once the Xcode project is rebuilt, open it and run the game on your iOS device. Verify that you’re able to move the Heroic Cube and that the wrinkle allowing you to move it with two fingers is now gone.

Where to Go From Here?

Congratulations, you’ve just finished learning the basics of developing with Unity and deploying on iOS! Here are some downloads with all of the code from the project up until this point: Unity Project, Xcode Project.

In the next part of the tutorial, you’ll build on this rudimentary game by enhancing the Heroic Cube’s movement and improving the scenery. You’ll also do a bit of debugging!

In the meantime, if you have any questions or comments about what you’ve done so far, jump into the conversation in the forums!

Christine Abernathy
Christine Abernathy

Christine is an Engineer on the Developer Advocacy team at Facebook. In this role, she is focused on helping grow the mobile developer ecosystem with emphasis on Android, iOS, and the mobile web. Prior to Facebook, Christine headed up engineering at Mshift, a mobile banking software provider, delivering iPhone apps and mobile browser-based products.

You can find Christine on Facebook.

User Comments

30 Comments

[ 1 , 2 ]
  • shippo0708 wrote:
    I get a bunch of these deploying to the iPhone :(

    ...

    Code: Select all

    (Filename:  Line: -1)

    UnityException: Index out of bounds.
      at MoveSimple.Update () [0x00000] in <filename unknown>:0

    (Filename:  Line: -1)



    The problem exists here:
    Code: Select all
           
    if (isTouchDevice) {
        clickDetected = (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began);
        touchPosition = Input.GetTouch(0).position;
    }


    When Input has no Touch, calling GetTouch (index : int) throws the exception. Check there is a touch first.

    More info about the Input system: http://docs.unity3d.com/Documentation/ScriptReference/Input.html
    OrangePco
  • Thank you for a great tutorial. Moving on to the next part !
    mslinklater
  • I was able to get rid of the "index is out of bounds" errors by changing the code in MoveSimple.js as shown (see the "if (clickDetected)" line):

    Code: Select all
    // Detect click and calculate touch position
        if (isTouchDevice) {
            clickDetected = (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began);
           if (clickDetected) {
               touchPosition = Input.GetTouch(0).position;
            }
        } else {
            clickDetected = (Input.GetMouseButtonDown(0));
            touchPosition = Input.mousePosition;
        }


    Clearly the update method gets called repeatedly, and isTouchDevice is going to always be true. The original code unconditionally set the touch position variable when there isn't a touch occurring during calls to "Update".
    bcwhite
  • Is there an easy way to debug and modify the touch events when using unity.. Presently the only way I see is to modify code in unity, re-build the unity project.. Run it in xcode and take a look at debug messages.. It would be good if there was a way to modify the touch related code in xcode.
    varun
  • I have just started using unity, and have been foilowing this first tutorial. I am stuck on the SmoothFollow import. I keep getting an error message when I try to attach it to the camera. "Can't add script behavior Smoothfollow. You need to fix all compile errors in the scripts first" Why would this be happening? thanks. Stacy
    aisha
  • Just wanted to say... great tutorial... really appreciate you taking the time to make it.. There are a lot of video ones out there but I find text ones easier to work along with so thank you.

    Also if anyone else has problems building the game, I kept getting lots of error codoes to do with ''Failed to cross compile'... After a bit of googling I found the problem, you need to make sure there are no spaces in your projects name... (if it was said in the tutorials already, sorry, must have missed it).

    Not got the simple game on my device next... got the last bit to read...
    draper3000
  • when i run show errors
    https://dl.dropboxusercontent.com/u/270 ... 4%20PM.png

    You can support for me.
    Thank you so much!
    paulduong
  • Thanks for ua Great Tutorial .....
    This helped me alot
    deepu.sandeep71
  • Great tutorial, thanks a bunch!!!
    I cannot seem to find parts 2 and 3 of this tutorial :s
    can someone help me with a direct link? thanks ;)
    kristadani
  • kristadani, yes, was not so easy to find it, but here you can find the other parts: http://www.raywenderlich.com/u/cabernathy
    NEOline
  • Hey! Thanks for such an amazing and easy to understand tutorial. I just have some issues with compiling errors. With the original code the Raycast and RaycastHit sent an error, marking that they should be UnityEngine.Raycast and UnityEngine.RaycastHit. I changed them and now the compiler throws an error asking for an instance of UnityEngine.Collider... here's the code:
    #pragma strict
    var speed:float=3.0;
    var rotateSpeed:float=10;
    function Update () {
    if(Input.GetMouseButtonDown(0)){
    var ray:Ray =Camera.main.ScreenPointToRay(Input.mousePosition);
    var hit:UnityEngine.RaycastHit;
    if(UnityEngine.Collider.Raycast(ray,hit,100.0)){
    Debug.Log("Moving the target");
    transform.Translate(Vector3.forward*speed);
    transform.Rotate(Vector3.up*rotateSpeed);
    }
    else{
    Debug.Log("");
    }
    }
    }
    Rahgnoruk
  • OOOK notices my mistake now. From the start I was allowing the autocomplete of the word Collider instead of collider... Sorry for the unnecesary post, feel free to remove it
    Rahgnoruk
  • Thank you for taking the time to create a fabulous tutorial
    NewD
  • I'm having bother with this section:

    if(UnityEngine.Collider.Raycast(ray,hit,100.0)){
    Debug.Log("Moving the target");
    transform.Translate(Vector3.forward*speed);
    transform.Rotate(Vector3.up*rotateSpeed);
    }
    else{
    Debug.Log("");
    }

    The editor does not recognise Raycast() as a method of Collider?
    elpuerco63
[ 1 , 2 ]

Other Items of Interest

Ray's Monthly Newsletter

Sign up to receive a monthly newsletter with my favorite dev links, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

Hang Out With Us!

Every month, we have a free live Tech Talk - come hang out with us!


Coming up in September: iOS 8 App Extensions!

Sign Up - September

RWDevCon Conference?

We are considering having an official raywenderlich.com conference called RWDevCon in DC in early 2015.

The conference would be focused on high quality Swift/iOS 8 technical content, and connecting as a community.

Would this be something you'd be interested in?

    Loading ... Loading ...

Our Books

Our Team

Tutorial Team

... 50 total!

Update Team

... 14 total!

Editorial Team

... 23 total!

Code Team

  • Orta Therox

... 3 total!

Translation Team

  • Marina Mukhina
  • Zihan Xu

... 33 total!

Subject Matter Experts

  • Richard Casey

... 4 total!