Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Apress Source Code

This repository accompanies Developing 2D Games with Unity: Independent Game Programming with C# by Jared Halpern (Apress, 2018).

Cover image

Download the files as a zip using the green button, or clone the repository to your machine using Git.


Release v1.0 corresponds to the code in the published book, without corrections or updates.

Contributions & Corrections

If you find any typos, errors in code, or otherwise incorrect information, please feel free to file an Issue in GitHub. See the file for more information on how you can further contribute to this repository.

General Notes

Credit: @RenatiusvanSander

As noted here, occasionally the Unity Editor will set the Z-coordinate on a newly created GameObject Transform to be negative. If this happens and the Z-coordinate is set to a negative number, you won't see it when the Scene plays. To fix this, change the Z-coordinate to be 0 on the GameObject Transform.


Chapter 3, Page 53

Credit: @omundy

After stopping the playing scene, add the animation for the player's idle state. From the Sprites folder, select the last two sprites from the Player32x32 sprite-sheet, titled: Player32x32_12 and Player32x32_13 and drag them onto the PlayerObject. When prompted by the Create New Animation save window, name the created animation-clip, "player-idle" and save to the Animations -> Animations folder.

Chapter 4

Credit: @josenerydev

Issue with format of file: OutdoorObjects.png. (fixed in GitHub repo)

Chapter 4, Page 93

In the Creating Tile Palettes section, the Tile Palette window in Unity 2018.3 is now located under Window -> 2D -> Tile Palette.

Chapter 4, Page 128

Credit: @omundy

Make sure to attach the RoundCameraPos script to the virtual camera object. Drag and drop the RoundCameraPos onto "CM vcam1".

Chapter 4, Page 137

Credit: @omundy

The interface has been updated in Unity 2018.3. The menu item "Edit Physics Shape" has been renamed to "Custom Physics Shape". After selecting Custom Physics Shape, click the "Generate" button on the right before editing.

Chapter 5, Page 147

Credit: @omundy

Create the GameObject in the hierarchy view (not project view).

Chapter 5, Page 161

Credit: @mprogers

In the Build the Consumable Script section, third paragraph, note that there is a distinction between the behavior of Scriptable Objects when running a project in the Editor, versus when running in a deployed (to device) build: Scriptable Objects cannot be used to save changes to data in a deployed build. More on this subject can be read here.

Chapter 5, Page 162

Credit: @omundy

In the Assembling Our Item section, third paragraph, rename the Scriptable Object, "Coin" (not "Item").

Chapter 5, Page 164

Credit: @omundy

In the Player Collisions section, the first line of code section // 3, should be:

print("Hit: " + hitObject.objectName);

Chapter 5, Page 166

Credit: @omundy

Steps 10 and 11 are duplicates of step 3 and can be disregarded.

Chapter 6, Page 198

Credit: @omundy

Under the heading Create the HealthBar Script, right-click in the MonoBehaviours folder and create a new C# script called HealthBar."

Chapter 6, Page 202-204

Credit: @omundy

Ensure a copy of the HealthBarObject is in the Hierarchy view and select it. Add the HealthBar script this HealthBarObject. When working with the HealthBar in these next 3 pages (202-204), work with the copy of HealthBarObject in the Hierarchy view, not the copy in the Prefab folder. Make sure to apply changes when you're done, so the changes propagate to the Prefab.

Note: The location of the button to apply changes to a prefab has changed in Unity 2018. The button is now located in the top right of the Inspector, in a drop-down menu called Overrides.

Chapter 6, Page 204

Credit: @omundy

The property, Character Category which appears in the source and in Figure 6-22 may be disregarded, or used later on in your game to broadly distinguish between what is/isn't an enemy, or the player (or even an NPC) instead of creating a tag for each character type.

Chapter 6, Page 207

Credit: @omundy

With InventoryObject selected, in the Canvas Scaler component, set Reference Pixels Per Unit to 32.

Chapter 7, Page 263

Credit: @omundy

In the The DamageCharacter() method section, the code should be added to the Enemy class.

Chapter 7, Page 269

Credit: @omundy

In the Refactoring Prefab Instantiation section, remove all four lines from Start() and add them to the new ResetCharacter() override.

After you add the ResetCharacter() method to the Player class, add the following method

private void OnEnable() {

Chapter 7, Page 275

Credit: @omundy

You'll notice when you run into the enemies they spin. Like you did with the PlayerObject, check Freeze Rotation for the Z axis inside the Rigidbody2D on the EnemyObject prefab.

Chapter 8, Page 287

Credit: @omundy

In the Enemy Walk Animation section, select the Enemy prefab then open the Animator window as seen in Figure 8-3.

Chapter 8, Page 357

Credit: @VADS

In the implementation of the GetQuadrant() method, disregard the first two variable declarations: Vector2 mousePosition = Input.mousePosition; and Vector2 playerPosition = transform.position; as they are not used.

Chapter 8, Page 360

Credit: @rdimitriev

In the method UpdateState(), the case for Quadrant.West: should be changed from: quadrantVector = new Vector2(-1.0f, 1.0f); to quadrantVector = new Vector2(-1.0f, 0.0f);