Beginning Unity 3D for iOS: Part 3/3

This is a post by Tutorial Team Member Christine Abernathy, an Engineer on the Developer Advocacy team at Facebook. You can also find her on Google+. Welcome to the third and final part the Beginning Unity 3D for iOS tutorial series! In the first part of this series, you toured the basic Unity tools, created […] By Christine Abernathy.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 6 of this article. Click here to view the first page.

Create the Launcher

Create an empty GameObject and add it to the scene. Name it Launcher. This represents the evil block empire that’s launching obstacles to put a stop to the Heroic Cube’s advances.

Using the Move Tool, place the launcher object in between the player and the finish line in the z direction and above the player. You can start with a Transform Position of 0,12,8 and tweak it as necessary.

Launcher adjustment.

The main reason for the launcher’s existence is to launch obstacles, so you need to give it some to launch!

Ammunition is typically created in Unity by designing GameObjects and then creating Prefabs that can be instantiated in the scene, as required, during gameplay. You’ll create an Obstacle GameObject, turn it into a Prefab, and then let the Launcher take care of launching it onto the hapless player.

Create the Obstacles

Create a cube GameObject and name it Obstacle. Set the Transform Scale to 2,2,2 so it’s bigger than the player and hence more intimidating. These are cubes that have gone to the Dark Side. :]

Give the obstacle an interesting look other than the default grey matter. To match the completed sample, first import a material from the Character Controller package: select Assets\Import Package\Character Controller, then select the constructor_done material and the relevant textures as shown in the image below, and finally click Import.

Import package material for obstacle.

The new material should show up in your Project View.

Material for obstacle imported.

Select the Obstacle GameObject. Change the render material by modifying the Inspector\Mesh Renderer\Materials\Element 0 property. Click on the circular icon next to the property to bring up the Select Material dialog.

Selection of obstacle material.

Select the constructor_done material you just imported. Close the Select Material dialog.

Obstacle material assigned.

Now you must tag the Obstacle GameObject so that later on you can take care of clearing out Obstacle instances of the scene when a new game is started.

For this, create a new tag named Enemy. Click on Inspector\Tag\Add Tag. The TagManager will show up in the right side panel. Expand the Tags array by clicking on the triangle next to the Tags label). Set the value of Element 0 to Enemy.

Adding an enemy tag.

Select the Obstacle GameObject and tag the object with the new Enemy tag.

Adding an enemy tag.

When Obstacle is instantiated, the code you’ll add will expect a Rigidbody component to be attached to the obstacle. Set that up by adding a Rigidbody. Select Component\Physics\Rigidbody (with Obstacle still selected):

Rigidbody component added to obstacle.

Click on the Assets folder in the Project View. Create a Prefab of your obstacle by selecting Assets\Create\Prefab. The Project View should show an empty Prefab. Name it Obstacle.

Empty Prefab created.

Note: If you have larger asset icons than in the screenshot above and wonder how you can get the list view of asset items, simply slide the slider below the asset list all the way to the left. :]

Drag the Obstacle GameObject into this new Prefab.

Obstacle assigned to Prefab.

The Prefab changes to a blue color to indicate that it has been assigned.

Now that you’ve created the Prefab as a reusable asset, you no longer need it in the scene. The launcher will take care of instantiating an Obstacle instance when needed. In the Hierarchy View, select the Obstacle GameObject, right-click and select Delete.

Release the Krak… Err, Obstacles

Next, complete the process by creating logic through a script to launch obstacles.

Create a new script asset and name it ObstacleLauncher.

Hint: You can also right-click in the Project View and select Create\JavaScript to create a script.

Open the new script and replace the stub functions with the following code:

var projectile : Rigidbody;
var speed = 5;
var maxObstacles = 2;
var launchInterval : float = 5.0;
var target : Transform;

private var nextLaunch : float = 0.0;
private var numObstaclesLaunched = 0;

function Start () {
    if (target == null) {
        // Find the player transform
        target = GameObject.FindGameObjectWithTag("Player").transform;
    }
}

function Update () {
    if ((numObstaclesLaunched < maxObstacles) && (Time.time > nextLaunch)) {
        // Set up the next launch time
        nextLaunch = Time.time + launchInterval;
        
        // Set up for launch direction
        var hit : RaycastHit;
        var ray : Ray;
        var hitDistance : float;
        
        // Instantiate the projectile
        var instantiatedProjectile : Rigidbody = Instantiate(projectile, transform.position, transform.rotation);
        
        // Simple block, try to get in front of the player
        instantiatedProjectile.velocity = target.TransformDirection(Vector3.forward * speed);     
        
        // Increment the launch count
        numObstaclesLaunched++;   
    }
}

The launcher is programmed to launch a certain number of obstacles just in front of the player. It therefore needs an input that represents the player. Previously, when assigning GameObjects to script, you’ve done so by dragging the GameObject to the script variable using the Editor. The Start() function code shows another way to do this.

In Start(), a check is made to see if there is no target assigned. If no target is found, the code looks for a GameObject with the Player tag and assigns this GameObject to the target variable.

The GameObject.FindGameObjectWithTag() function call is typically an expensive call, as it needs to look through all GameObjects. So you’ll want to call this in Start() (which gets called once) and avoid putting it in, say, Update() (which gets called multiple times).

In the code, Update() first checks if the Launcher has sent out the maximum obstacles allowed. If not, it also checks if a set time interval has passed. This is to avoid launching too many obstacles within a short amount of time.

If it’s time to launch another obstacle, then the Obstacle Prefab is instantiated at the position and rotation corresponding to the Launcher. The instantiated obstacle is then launched in a direction that matches the player’s forward direction, so as to land just in front of the player.

Now save your code and tie up loose ends. First, attach the ObstacleLauncher script to the Launcher GameObject. Assign the Obstacle Prefab to the projectile variable in the script (you can drag the Prefab from the Assets list to the variable). Assign the Player GameObject to the target variable in the script.

Launcher variables assigned.

Play the game in the Unity Editor and verify that the blocks are launched in front of the Heroic Cube as it moves around. Adjust the launcher’s position so that the blocks are launched in between the player and the finish line. You can also adjust the finish line by moving the Finish Line GameObject in the z direction, away from the player.

Hint: You can set the Transform Position to 0,0,2. When you move the Finish Line object, the child objects come along for the ride, which is one perk of parenting or grouping related GameObjects.

Game view of launcher test.

You have most of the game functionality working now. Next you’ll pull everything together with a mission control script that displays the game timer, coordinates the gameplay and resets the scene to start a new game.

Christine Abernathy

Contributors

Christine Abernathy

Author

Over 300 content creators. Join our team.