Welcome to Part 3 in this series on making a 2D sprite-based game with Unity 3D. In Part 1 I introduced you to the tools we’ll be using to make a Lode Runner style action game and inPart 2 we created the level sprites and built our first level. In this tutorial we’re going to be adding in the player, hooking up the scripts and adding collision to the ladders and ropes so that you’ll finally be able to run the character around in your levels.
This tutorial assumes that you have already followed along with Part 2 of this series so your project should be ready to continue on with the steps below. If you haven’t already done Part 2, you should go back and do that first so you can get a full understanding of how everything fits together. If you’d rather skip ahead, you can download the project up to this point. You can also click here to see how the game will look at the end of Part 3.
Making the Player Sprite Atlas
If you’ve been following the series, I know you’re excited to get the player character running around in the game, so the first thing we need to do is create a sprite atlas inTexturePacker.
Download the source sprite .png’s and unzip the file somewhere on your hard drive. If you already downloaded the sprites and added them to your project in Part 2, then you can skip this step.
Launch TexturePacker and then drag & drop all of the
.png
files from the
sprites/player
folder into the
Sprites
panel.
Texture Settings / Layout:
Set
Algorithm
to
Basic
Set
Border Padding
to
1
Set
Shape Padding
to
1
Uncheck
Trim
Texture Settings / Output:
Leave the
Data format
set to
cocos2d
.
Under
Data File
, click the little “…” button and browse to the location in your project’s Asset folder where you want to store your sprites (I put mine in
Assets/SpriteAtlases
), name the file “
player
” and then click
Save
.
TexturePacker automatically adds the
.plist
extension to the
Data File
, but Unity wants the file to be
.xml
. So in the text field, replace
.plist
with
.xml
.
The
Texture File
path should already be set to the same location as the
.xml
file except that it will have a
.png
extension so there’s nothing to do there.
If you followed the steps above, then your settings in TexturePacker should look like this (click the image to see a larger version):
Now if you click the
Publish
icon in
TexturePacker
and then switch back to Unity, you should see a
player.png
file and a
player.xml
file in the
SpriteAtlases
folder in the Project view.
If you don’t already have the project open in Unity, open it now and then load the scene that you created in Part 2 (eg.
level1.scene
).
We need to make a couple of changes to the sprite atlas in Unity so that it looks correct.
Select the
player.png
file in the Project tab. In the Inspector change the
Filter Mode
to
Point
.
Click the
Override for Web
box, set the
Format
to
Truecolor
and then click
Apply
.
Making the Player Sprite
Now we’re ready to turn the player’s sprite atlas into animated sprites using theOrthello 2D plugin.
The Sprite Container:
In the Unity Project tab, expand the Orthello folders:
Orthello –> Objects –> Sprites –> SpriteAtlas
and then drag the
SpriteAtlas-Cocos2D
object into the Hierarchy.
In the Hierarchy tab, expand the
OT
object and then the Containers object and you will see your new container with a name something like “Container (id=-6840)“. This is the Container that will hold all of our
player
sprites from the atlas we made so you can rename the Container to something obvious like “player“.
Drag the
player.png
from the
SpriteAtlases
folder and drop it on the “
OTSprite Atlas Cocos 2D
” script’s
Texture
slot.
Drag the
player.xml
from the Project,
SpriteAtlases
folder and drop it on to the
Atlas Data File
slot. Now if you drop down the little Atlas Data arrow, you should see that it’s populated with all the sprite atlas data that TexturePacker generated for us.
Setting Up The Player Animations:
Now we need to assign all of the frames from the sprite atlas to individual animations.
Drag an
Animation
object from
Orthello –> Objects –> Sprites
into the Hierarchy. This will add a new object under
OT –> Animations
named something like “Animation (id=-4320)“. Rename this object to “
player anims
“.
With the new “
player anims
” OTAnimation still selected, adjust the settings to match those in the following image. To populate the
Container
field, drag & drop the “
player
” object from
OT –> Containers
on to the
Container
field.
Click the image to see all of the animation settings:
Making The Player Sprite
Next find the
AnimatingSprite
object in
Orthello –> Objects –> Sprites
object in the Project tab and drag it into the Hierarchy, this will make a new object in the scene with a name like “Animating Sprite (id=-23050)“. Rename this object “
player
“.
With the new
player
object still selected in the Hierarchy, drag the “
player anims
” object on to the
Animation
slot. The
Sprite Container
slot should automatically fill with a reference to the “
player
” container object, if it doesn’t you can drag & drop that onto the slot.
Now you should see the player sprite in your scene and if you press
Play
in Unity, the sprite will animate through all of the frames in all of the animations. We don’t want the animation to play on start so uncheck the
Play On Start
checkbox.
Adding Collision To The Player
In order for the player to collide correctly with the ladder and rope colliders we’ll be creating later, we need to set the following.
With the the
player
“OTAnimating Sprite” still selected in the Hierarchy, check the check box next to
Collidable
. This will automatically add a Rigidbody component to the object.
Click the dropdown list next to
Physics
and select
Custom
from the list.
Under
Transform
, set the
Scale Z
to
1
.
Change the
Depth
to
-1
.
Under
Box Collider
, set
Center Y
to
-0.1
and
Z
to
1
. Change
Size X
to
0.45
,
Y
to
0.6
and
Z
to
0.4
.
If you followed the steps above, the settings on the player sprite should look like the following image.
Click on the image to see all of the settings:
Changing the Depth to -1 and the Center Z to 1 on the Box Collider will position the Collision at 0 on the Z axis while moving the player sprite 1 unit towards the camera. This has 2 effects: it makes sure that the player will always be visible in front of the level sprites while keeping the collision at 0 on the Z so that it will collide with the ladder and rope triggers. It sounds kinda strange, but you can see how it should look in this screen shot:
Setting Up The Shooting Animation
We need to add another animating sprite so that when you press the fire button, you’ll see a bullet blob animate from the player and hit the ground.
The Shoot Animation:
Drag an
Animation
object from
Orthello –> Objects –> Sprites
into the Hierarchy. This will add a new object under
OT –> Animations
named something like “Animation (id=-4320)“. Rename this object to “
shoot anim
“.
With the new “
shoot anim
” OTAnimation still selected, adjust the settings to match those in the following image. To populate the Container field, drag & drop the “level” object from
OT –> Containers
on to the
Container
field. Remember that we already added the shoot sprite animation to the level sprite atlas in Part 2 of the series.
The Shoot Sprite
Next find the
AnimatingSprite
object in
Orthello –> Objects –> Sprites
in the Project tab and drag it into the Hierarchy, this will make a new object in the scene with a name like “Animating Sprite (id=-23050)“. Rename this object “
shoot
“.
With the new
shoot
object still selected in the Hierarchy, drag the “
shoot anim
” object on to the
Animation
slot. The
Sprite Container
slot should automatically fill with a reference to the “
level
” container object, if it doesn’t you can drag & drop that onto the slot.
Set the
Transform Position X
to
-1
so that the sprite is position to the left of the player’s sprite.
Set the
Depth
to
-1
so that the sprites will appear in front of the level sprites.
Set the
Frame Index
to
18
.
Now you should see the shoot sprite in your scene and if you press
Play
in Unity, the sprite will animate through all of the frames in all of the animations. We don’t want the animation to play on start so uncheck the
Play On Start
checkbox.
We only want to see the shoot sprite when the player is actually shooting so uncheck the checkbox next to
Mesh Render
on the
shoot
sprite. This will hide the sprite in the scene until we show it again later with a script.
Parenting The Shoot Sprite
We want the sprite to move with the player and we also need to flip the sprite so that it’s either on the player’s left or right side depending on which way the character is facing.
Go to Game Object –> Create Empty
Rename this object to “
shoot parent
” and make sure the
X, Y, Z Position
on the object is set to
zero
.
In the Hierarchy, drag and top the
shoot
sprite on to the
shoot parent
so that the
shoot
sprite becomes a child of the
shoot parent
object.
Drag and drop the
shoot parent
object on to the
player
sprite so that it’s a child of the
player
.
If you followed all the steps so far, your Hierarchy should look something like the following image. Note that I put all of my level tiles under an empty game object named
LEVEL
to keep things organized.
Note that in order for the scripts to work, the child objects under the player must be named exactly as shown in the above image.
Hooking Up The Scripts
We’re finally ready to add the scripts so that the player can move!
Download the player scripts
and unzip the file somewhere on your hard drive.
Drag the
Scripts
folder from the
.zip
into your project’s
Asset
folder.
Create an empty game object by going to
Game Object –> Create Empty
Rename the new object to something like “
Scripts
“.
Drag and drop the
xa.cs
file from the Project tab onto the
Scripts
object in the Hierarchy.
Drag and drop the
player.cs
and the
playerAnims.cs
files from the Project tab on to the
player
object in the Hierarchy.
Make sure that the player is positioned above a brick tile so that she has something to stand on. Remember that it’s the player’s Box Collider that actually collides with objects in the world and not the visible sprite object, so the box will be positioned at something like 0,0,-1 (X and Y can be anywhere in the level but Z should always be -1).
Now if everything is setup correctly, when you press Play in Unity the player should stand on a brick tile without falling through it. And if you press left and right on the keyboard the player should move and the run animations should play.
Describing how the scripts work is beyond the scope of this tutorial, but I did add comments to the scripts that should hopefully help you understand how everything is working. If you have questions about anything in the scripts, please feel free to ask in the comments below or email me directly.
Adding The Ladder Colliders
In order for the ladders to work, we need to add colliders to them.
Creating A Ladder:
Go to
GameObject –> Create Other –> Cube
Rename the Cube to something like “
Ladder
“.
Open the
Tag Manager
by going to to
Edit –> Project Settings –> Tags
Under
Tags
in the next available slot (probably Element 1) type “
Ladder
” and then in the next slot after that, type in “
Rope
” (without the quotes).
While we’re here, we need to add another layer. Under the next empty
User Layer
(probably User Layer 9), type “
NoDraw
” (without the quotes).
Now click on the Ladder cube you created before and change the Tag to “
Ladder
” and then change the Layer to “
NoDraw
“.
Hiding Objects In The Game View:
You’ve probably noticed that the Ladder collider is visible in the Game view but we don’t want to see these in the actual game. To hide them, we need to make a change to the camera.
Click on the
Main Camera
object in the Hierarchy.
Under
Camera
, drop down the list next to
Culling Mask
and click on “
NoDraw
” to deselect it. Now any object that is in the “NoDraw” layer will be hidden in the Game view.
Sizing And Positioning The Ladder:
Every ladder in the scene needs to have one of these Ladder colliders and we need to adjust the size of the Ladder colliders to match the height of each of the ladders in the level. The ladder collider needs to be 1 unit taller than the visible ladder – so if your ladder is 4 tiles (sprites) tall, then the collider needs to be 5 units tall.
Assuming your ladder is 4 sprites high: Select the
Ladder
collider and change the
Scale Y
to
5
(1 unit taller than the visible ladder).
Snap the Ladder collider to one of the lower corners of the bottom sprite using the
Vertex Snap
feature in Unity.
You can duplicate this object, resize the Y and snap it to all the other ladder sprites in your level.
Your ladder should look like this (click to see a larger version):
Now if you press
Play
in Unity and then walk the player over to the ladder, she should be able to climb up and down the ladder, the player’s sprite should be playing the climb animation and you should be able to exit the ladder at the top and bottom levels and also fall off the ladder if you exit somewhere in the middle.
Adding the Rope Colliders
The rope colliders follow pretty much the same setup as the ladders.
Creating A Rope:
Go to
GameObject –> Create Other –> Cube
Rename the Cube to something like “
Rope
“.
Change the
Tag
to “
Rope
” and then change the Layer to “
NoDraw
“.
Sizing And Positioning The Rope:
Like the Ladders, every rope in the scene needs to have one of these Rope colliders. But unlike the Ladders, the Rope colliders must be the same width as your rope sprites.
Assuming your rope is 4 sprites wide: Select the Rope collider and change the
Scale X
to
4
(Y and Z scale should be 1).
Snap the Rope collider to one of the lower corners of the bottom sprite using the Vertex Snap feature.
You can duplicate this object, resize the X and snap it to all the other rope sprites in your level.
Your rope should look like this (click to see a larger version):
Now if you press Play in Unity and then walk the player over to the rope, she should be able to climb left and right along the rope, you should see the rope hang animation playing and if you press the down arrow while hanging from the rope, she should let go of the rope and fall.
Conclusion
Now you have everything you need to make levels that support the player’s full suite of movements: running, ladder climbing and rope shimmy. In the next tutorial, we’re going to be adding the scoring system, breaking out brick tiles and picking up objects.
When I began this series, It was my intention to include enemies that could follow the player around the level using behaviors similar to the original Lode Runner game. However my time has become increasingly limited and my programming skills aren’t fully up to the task of recreating their AI so I might not be able to get AI into this the series.
If you are a programmer who would like to contribute an AI behavior solution to this tutorial series, please contact me.