How to Make a Game Like Jetpack Joyride in Unity 2D – Part 3

In the final part of this series, you will generate some coins and lasers, construct a scrolling background, all to some fancy beats. By Mark Placzek.

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

Adding New Parameters to GeneratorScript

Open GeneratorScript and add the following instance variables:

public GameObject[] availableObjects;
public List<GameObject> objects;

public float objectsMinDistance = 5.0f;
public float objectsMaxDistance = 10.0f;

public float objectsMinY = -1.4f;
public float objectsMaxY = 1.4f;

public float objectsMinRotation = -45.0f;
public float objectsMaxRotation = 45.0f;

The availableObjects array will hold all objects that the script can generate (i.e. different coin packs and the laser). The objects list will store the created objects, so that you can check if you need to add more ahead of the player or remove them when they have left the screen.

Note: Just as with rooms, you can create several lasers or coins at the beginning of the level where you don’t want to rely on random generation code. Just don’t forget to add them to the objects list.

The variables objectsMinDistance and objectsMaxDistance are used to pick a random distance between the last object and the currently added object, so that the objects don't appear at a fixed interval.

By using objectsMinY and objectsMaxY, you can configure the minimum and maximum height at which objects are placed, and by using objectsMinRotation and objectsMaxRotation you can configure the rotation range.

Adding the Method to Add a New Object

New objects are added in the following AddObject method in a similar way to how rooms are added. Add the following to the GeneratorScript:

void AddObject(float lastObjectX)
{
    //1
    int randomIndex = Random.Range(0, availableObjects.Length);
    //2
    GameObject obj = (GameObject)Instantiate(availableObjects[randomIndex]);
    //3
    float objectPositionX = lastObjectX + Random.Range(objectsMinDistance, objectsMaxDistance);
    float randomY = Random.Range(objectsMinY, objectsMaxY);
    obj.transform.position = new Vector3(objectPositionX,randomY,0); 
    //4
    float rotation = Random.Range(objectsMinRotation, objectsMaxRotation);
    obj.transform.rotation = Quaternion.Euler(Vector3.forward * rotation);
    //5
    objects.Add(obj);            
}

This method takes the position of the last (rightmost) object and creates a new object at a random position after it, within a given interval. By calling this method, you create a new object off screen each time the last object is about to show on the screen. This creates an endless flow of new coins and lasers.

Here is the description of each code block:

  1. Generates a random index to select a random object from the array. This can be a laser or one of the coin packs.
  2. Creates an instance of the object that was just randomly selected.
  3. Sets the object's position, using a random interval and a random height. This is controlled by script parameters.
  4. Adds a random rotation to the newly placed objects.
  5. Adds the newly created object to the objects list for tracking and ultimately, removal (when it leaves the screen).

With the code in place, the only thing left to do is actually use it!

Generating and Removing Objects When Required

Add the following in the GeneratorScript:

void GenerateObjectsIfRequired()
{
    //1
    float playerX = transform.position.x;
    float removeObjectsX = playerX - screenWidthInPoints;
    float addObjectX = playerX + screenWidthInPoints;
    float farthestObjectX = 0;
    //2
    List<GameObject> objectsToRemove = new List<GameObject>();
    foreach (var obj in objects)
    {
        //3
        float objX = obj.transform.position.x;
        //4
        farthestObjectX = Mathf.Max(farthestObjectX, objX);
        //5
        if (objX < removeObjectsX) 
        {           
            objectsToRemove.Add(obj);
        }
    }
    //6
    foreach (var obj in objectsToRemove)
    {
        objects.Remove(obj);
        Destroy(obj);
    }
    //7
    if (farthestObjectX < addObjectX)
    {
        AddObject(farthestObjectX);
    }
}

Here's the breakdown of how this method checks if an object should be added or removed:

  1. Calculates key points ahead and behind the player. If the laser or coin pack is to the left of removeObjectsX, then it has already left the screen and is far behind. You will have to remove it. If there is no object after addObjectX point, then you need to add more objects since the last of the generated objects is about to enter the screen.The farthestObjectX variable is used to find the position of the last (rightmost) object to compare it with addObjectX.
  2. Since you cannot remove objects from an array or list while you iterate through it, you place objects that you need to remove in a separate list to be removed after the loop.
  3. This is the position of the object (coin pack or laser).
  4. By executing this code for each objX you get a maximum objX value in farthestObjectX at the end of the loop (or the initial value of 0, if all objects are to the left of origin, but not in our case).
  5. If the current object is far behind, it is marked for removal to free up some resources.
  6. Removes objects marked for removal.
  7. If the player is about to see the last object and there are no more objects ahead, call the method to add a new object.

To make this method work, add a call to GenerateObjectsIfRequired to GeneratorCheck just below GenerateRoomIfRequired:

GenerateObjectsIfRequired();

Like with the room prefab, this method is called a few times per second, ensuring that there will always be objects ahead of the player.

Setting up Script Parameters

To make the GeneratorScript work, you need to set a few of its parameters. Switch back to Unity and select the mouse GameObject in the Hierarchy.

Find the Generator Script component in the Inspector and make sure that the Prefabs folder is open in the Project view.

Drag the coins_v Prefab from the Project view to the Available Objects list in the GeneratorScript component. Next, drag the laser Prefab from the Project view to the Available Objects list also.

That’s it! Run the scene.

Now this looks like an almost complete game.

Adding GUI Elements

What’s the point of collecting coins if you can’t see how many coins you have collected? Also, There's no way for the player to restart the game once they have died. It's time to fix these issues by adding a couple of GUI elements.

Displaying Coin Count

Open the MouseController script and add the UnityEngine.UI namespace, as you will now be wielding the power of Unity’s new GUI system!

using UnityEngine.UI;

Switch back to Unity to begin creating the UI. Click GameObject/UI/Image to add an Image element.

If this is the first UI element in your scene, Unity will automatically create a couple objects to get you started: a Canvas and an EventSystem. You will notice your new Image element is a child of the canvas. All elements within the canvas will be rendered after scene rendering and by default will overlay the available screen space, which is perfect for your UI score and any other information you want to display to the player. The EventSystem is responsible for processing raycasts and inputs to your scene’s UI and handling their respective events.


In the Scene view, the canvas exists somewhat separately from the rest of your level, however, in the Game view it is rendered on top.

In the Scene view, the canvas exists somewhat separately from the rest of your level, however, in the Game view it is rendered on top.

Now click GameObject/UI/Text to add a Text element.

Those are the only two elements you need to display the coin count; now to get them positioned and styled.

Select the Image Object in the Hierarchy and rename it coinImage in the Inspector. Unity’s UI uses a unique Rect Transform component, a more 2D-centric take on the normal Transform component. The Rect Transform additionally exposes parameters to control size, anchor and pivot point of your UI elements. This allows control of your UI scale and position with respect to screen size and aspect ratio.

Note: For a more extensive explanation of the UI system, I highly recommend having a look at our Introduction to Unity tutorial. The awesome Brian Moakley shows you how to create a start menu for this very game!

Note: For a more extensive explanation of the UI system, I highly recommend having a look at our Introduction to Unity tutorial. The awesome Brian Moakley shows you how to create a start menu for this very game!

You want your image to be locked in position near the top left of the screen.

Have a look at the box in the top left of the Rect Transform component. This represents the Anchor and pivot point of your UI element. Tapping the box will bring up a grid of options titled Anchor Presets. These allow you to adjust the Anchor and stretch of the element. Holding Shift at the same time will also set the pivot and holding Alt will set the position. Let's get these UI elements set up.

  1. Tap the coinImage Anchor Preset box and holding both Alt and Shift, tap the top left box in the grid.
  2. Set Pos X to 15, and Pos Y to -15.
  3. Adjust both the height and width to 70.
  4. Still in the inspector, you can set the sprite you wish to display in the Image component. Open the Sprites folder in the Project view and drag the coin sprite to the Source Image property.
    It should look like this:

Now to adjust the tiny little mouse sized text element. Your jetpacking hero may be a mouse, but let’s assume your user is not.

  1. Select the Text in the hierarchy and drag it over the coinImage. You want these UI elements to stick together no matter the screen size or aspect ratio. Making the text a child of the image will make that simple.
  2. In the Inspector, rename Text to coinsCollected.
  3. Click the Anchor Preset box and holding Alt and Shift click on the left middle grid square.
  4. Set the Pos X to 75 and the height to 70

If everything looks the same as below, you are ready to head to the Text component to adjust the Font and Alignment.

Make the following adjustments to the Text component:

  1. Change the Text from New Text to 0.
  2. Increase the font size to 60.
  3. In the Alignment property, change the top vertical alignment to middle.
  4. Change the horizontal overflow from Wrap to Overflow.
  5. Finally pick a nice yellow or coin-gold for the color property (I used 245 red, 200 green, and 80 blue).

It should look something like this:

You are already counting the coins collected in the MouseController script, so let's hook that value up to the coinsCollected Text.

Create a new public instance variable in the MouseController.

public Text coinsCollectedLabel;

In the CollectCoin method, just after coins++;, add the following line of code:

coinsCollectedLabel.text = coins.ToString();

The coins integer is simply converted to a string and applied to the text property of the Text element.

Finally, back in Unity, drag the coinsCollected Text element from the hierarchy to the coinsCollectedLabel in the MouseController:

Hit run and start racking up those coins! The number should be displayed in the corner of the screen.

Mark Placzek

Contributors

Mark Placzek

Author

Toby Flint

Tech Editor

Chris Belanger

Editor

Sean Stewart

Illustrator

Sean Duffy

Final Pass Editor

Over 300 content creators. Join our team.