Unity 2D Techniques: Build a 2D Pinball Game

In this tutorial, you’ll learn how to use Unity’s 2D techniques to build an old-school pinball game using sorting groups, the mesh editor and more. By Ben MacKinnon.

4.9 (10) · 1 Review

Download materials
Save for later
Update note: Ben MacKinnon updated this tutorial for Unity 2019.3. Arai wrote the original.

In this Unity 2D Techniques tutorial, you’ll learn advanced tips and tricks for building 2D games in Unity. Learn how to apply these techniques while building an epic old-school pinball game called Snap and Strike!

Should you find this tutorial too advanced, work through this starter on Unity 2D games How to Make a Game Like Jetpack Joyride in Unity 2D tutorial first. Once done, come back and level up your 2D Unity skills even further.

There’s minimal scripting in this tutorial, but it’ll be easier to follow if you have some basic knowledge of C# programming. To brush up your skills, check out our Introduction to Unity Scripting tutorial.

Note: This tutorial assumes that you’re comfortable working with Unity and you know your way around Unity’s UI. If you’re not, take the time to read through our Introduction to Unity UI tutorial first.

By the time you’ve finished this tutorial, you’ll know more about:

  • Sorting groups
  • Sprite masks
  • 9-slice sprites
  • 2D colliders and joints
  • The mesh editor
  • Types of effectors and 2D physics materials

It’s time to get the (pin)ball rolling!

Getting Started

First, download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.

Make sure you’re using Unity version 2019.3, which you can download through the Unity Hub.

Unzip the materials and open the starter project in Unity. When the project launches, switch to the Scene view and make sure you’re using 2D mode.

Where to find 2D mode

Exploring the Starter Project

Start by exploring the project.

Double-click the PinballWizard scene in Assets/RW/Scenes. In the Hierarchy, you can see the GameObjects separated into categories:

  • SoundObjects
  • Main camera
  • Hotspots
  • Static colliders
  • Static panel
  • Animations

Click Play and take a look at the current state of the pinball table.

Unsorted pinball layers

Well, things are certainly animating! But the images are currently fighting each other to render on-screen.

Your first task is to adjust the Sorting Layers for the last three groups so they render in the correct order.

Adjusting Your Sorting Layers

A Sorting Group is a group of components you use to create consolidated Sorting Layers. That is, multiple instances of a prefab with multiple objects on different sorting layers.

The Sorting Layers in this project should be in the following order:

  • Panel (lowest layer)
  • Efx
  • Logo
  • Obstacles
  • Top
  • Cover (highest layer)

Now, adjust your Sorting Layers as follows:

The static colliders of the pinball table.

To show this group, select Static Panel in the Hierarchy. Then, click Add Component and select Rendering ▸ Sorting Group. In the newly-added Sorting Group component, find the Sorting Layer drop-down and select Panel.

Editing the Sorting Layer.

In the Sorting Layer drop-down, select Efx and click Play.

Pinball game with proper animation layers

  1. Static colliders: These objects with colliders form the basic collision structure of the pinball table. A sorting group is not required here.
  2. Static panel: Contents in this group are hidden.
  3. Animations: Select Animations in the Hierarchy and click Add Component. Then, select Rendering ▸ Sorting Group.

You’ll find that most of the nuts and bolts for the pinball game are already in the starter project. Now it’s time for the fun stuff: adding the action!

Getting the Ball Rolling

First, you need to create an empty GameObject to hold your work.

Do this by right-clicking an empty space in the Hierarchy and selecting Create Empty. Now, name the new object Interactive Parts.

In the Inspector, reset its Transform values by clicking the Settings icon and selecting Reset.

Next, create seven more empty GameObjects as children of Interactive Parts and name them:

  • ScrollingTrees
  • BillBoard
  • Plunger
  • Flippers
  • Float Piece Area
  • Road Tunnel Zone
  • Bumpy Parts

Be sure to reset all their Transform values as well.

New GameObjects

Note: Create these GameObjects quickly by selecting the Interactive Parts GameObject and pressing Alt-Shift-N to create a child GameObject. Then use Control/Command-D to duplicate it six times! Then all that’s left is to rename each GameObject.

Scrolling Trees

Next, you’ll use a Sprite Mask to display only a part of an animation. It’ll look like this:

Unity 2017 2D Techniques

Here’s how you do it:

  1. Go to Assets/RW/Sprites, drag trees_circle onto ScrollingTrees in the Hierarchy and name the sprite instance TreeCircle.
  2. In the Inspector, set the Transform Position to (X:-0.7, Y:2.2, Z:0) and set its Rotation to (X:0 Y:0 Z:17).
  3. Right-click ScrollingTrees in the Hierarchy, select 2D Object ▸ Sprite Mask and name it TreeMask.
  4. Set the Transform Position to (X:-1.91, Y:2.58, Z:0) and set Scale to (X:1.48, Y:1.58, Z:1).
  5. In the Inspector, go to the Sprite field of the Sprite Mask component, click on the circle icon to launch the list of sprite assets, and select trees_mask.
  6. Select TreeCircle in the Hierarchy. Using the Inspector, find the Sprite Renderer and select Efx from the Sorting Layer drop-down. From the Mask Interaction drop-down, select Visible Inside Mask.

Editing the Sprite Renderer.

Scripting the Animation

With the graphics in place, it’s time to add the script that controls the animation.

Double-click Assets/RW/Scripts/AnimateController to open it in your code editor.

Add the following variables below the existing ones:

public GameObject treeObject;
private float turnSpeed = 30f;

Then add the following FixedUpdate:

private void FixedUpdate()
    if (treeObject != null)
        treeObject.transform.Rotate(new Vector3(0f, 0f, turnSpeed * Time.fixedDeltaTime));

This rotates the sprite assigned to the treeObject variable at a consistent speed, regardless of whether the player’s frame rate is 30 FPS, 60 FPS, or fluctuates in between. turnSpeed allows you to tweak how fast the trees rotate.

Note: You can learn more about FixedUpdate in the official Unity docs.

Click Save and return to Unity.

Select ScrollingTrees in the Hierarchy, click Add Component and select Scripts ▸ Animate Controller. Then drag TreeCircle from the Inspector onto the Tree Object field.

Click Play to preview your new working animation.

The trees moving on the pinball table.

Adding the Billboard

There’s no sense playing pinball if you can’t try to beat your last score! To help you do that, you’ll add an animated billboard with flashing lights next.

Open Assets/RW/Sprites/ani_billboard and drag aniBillbord0001 into BillBoard in the Hierarchy. Name the child instance AniBillboard.

In the Sorting Layer drop-down, select Top. Click Add Component and select Miscellaneous ▸ Animator.

In the Inspector, open the Controller field of Animator and click the circle icon beside it to launch the list of animator controllers. Select ani_Billboard.

Open the Animation window from Menu ▸ Window and click Play to preview what the billboard will look like.

Animated billboard

The 9-slice sprite is another useful 2D technique. This feature preserves the corners and borders of graphical elements when resizing.

Go to Assets/RW/Sprites/ani_billboard and select one of the sprites. In the Inspector, click the Sprite Editor icon to edit the stretchable parts of the sprite.

The sprites used for this animation come prepped with a 9-slice sprite, so resizing them won’t be a problem now. Phew!

Here’s what you achieve using 9-slice on your billboard:

9-slice example