How to Make a Game Like Jetpack Joyride in Unity 2D – Part 2
In the second part of a three part series, you will be generating a series of endless rooms, allowing the user to fly through them. By Mark Placzek.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How to Make a Game Like Jetpack Joyride in Unity 2D – Part 2
40 mins
- Getting Started
- Making the Mouse Fly Forward
- Setting the Mouse Velocity
- Making the Camera Follow the Player
- Adjusting the Camera Offset
- Generating an Endless Level
- Creating a Room Prefab
- The Idea Behind the Room Generation
- Adding a Script to Generate Rooms
- The Method to Add a New Room
- Checking if a New Room is Required
- Setting the Script Options and Enjoying
- Animating the Mouse
- Creating Animations
- Adding Run Animation Frames
- Adding the Fly Animation Frame
- Adjusting the Animator and Run Animation Settings
- Creating Animation Transitions
- Adding a Transition Parameter
- Checking if the Mouse is Grounded
- Using Layers to Define What is Ground
- Checking if the Mouse is Grounded
- Setting the MouseController Script Parameters for Ground Check
- Enabling and Disabling the Jetpack Flames
- Where to Go From Here?
Checking if a New Room is Required
Ready for some more code? Add the following GenerateRoomIfRequired
method:
private void GenerateRoomIfRequired()
{
//1
List<GameObject> roomsToRemove = new List<GameObject>();
//2
bool addRooms = true;
//3
float playerX = transform.position.x;
//4
float removeRoomX = playerX - screenWidthInPoints;
//5
float addRoomX = playerX + screenWidthInPoints;
//6
float farthestRoomEndX = 0;
foreach (var room in currentRooms)
{
//7
float roomWidth = room.transform.Find("floor").localScale.x;
float roomStartX = room.transform.position.x - (roomWidth * 0.5f);
float roomEndX = roomStartX + roomWidth;
//8
if (roomStartX > addRoomX)
{
addRooms = false;
}
//9
if (roomEndX < removeRoomX)
{
roomsToRemove.Add(room);
}
//10
farthestRoomEndX = Mathf.Max(farthestRoomEndX, roomEndX);
}
//11
foreach (var room in roomsToRemove)
{
currentRooms.Remove(room);
Destroy(room);
}
//12
if (addRooms)
{
AddRoom(farthestRoomEndX);
}
}
It only looks scary, but in fact it is quite simple. Especially if you keep in mind the ideas previously described:
- Creates a new list to store rooms that need to be removed. A separate list is required since you cannot remove items from the list while you are iterating through it.
- This is a flag that shows if you need to add more rooms. By default it is set to true, but most of the time it will be set to false inside the first
foreach
loop. - Saves player position. (You'll mostly only use the x-coordinate when working with the mouse's position though).
- This is the point after which the room should be removed. If room position is behind this point (to the left), it needs to be removed. You need to remove rooms, since you cannot endlessly generate rooms without removing them after they are not needed. Otherwise you will simply run out of memory.
- If there is no room after the
addRoomX
point, then you need to add a room, since the end of the level is closer than the screen width. - In
farthestRoomEndX
, you store the point where the level currently ends. You will use this variable to add a new room if required, since a new room should start at that point to make the level seamless. - In the
foreach
loop you simply enumeratecurrentRooms
. You use the floor to get the room width and calculate theroomStartX
(the point where the room starts, i.e. the leftmost point of the room) androomEndX
(the point where the room ends, i.e. the rightmost point of the room). - If there is a room that starts after
addRoomX
then you don’t need to add rooms right now. However there is no break instruction here, since you still need to check if this room needs to be removed. - If the room ends to the left of the
removeRoomX
point, then it is already off the screen and needs to be removed. - Here you simply find the rightmost point of the level. This is the point where the level currently ends. It is used only if you need to add a room.
- This removes rooms that are marked for removal. The mouse GameObject already flew through them and thus they need to be removed.
- If at this point
addRooms
is still true then the level end is near.addRooms
will be true if it didn’t find a room starting farther than the screen's width. This indicates that a new room needs to be added.
Phew, that was a lot of code — but you’ve made it!
You will need to periodically execute GenerateRoomIfRequired
. One way to accomplish this is with a Coroutine.
Add the following to the GeneratorScript:
private IEnumerator GeneratorCheck()
{
while (true)
{
GenerateRoomIfRequired();
yield return new WaitForSeconds(0.25f);
}
}
The while
loop will ensure any code will continue to be executed whilst the game is running and the GameObject is active. Operations involving List<>
can be performance limiting; therefore, a yield
statement is used to add a 0.25 second pause in execution between each iteration of the loop. GenerateRoomIfRequired
is only executed as often as it is required.
To kick off the Coroutine, add the following code to the end of the Start
method in GeneratorScript:
StartCoroutine(GeneratorCheck());
Setting the Script Options and Enjoying
Return to Unity and select the mouse GameObject in the Hierarchy. In the Inspector, find the GeneratorScript component.
Drag room1 from the Hierarchy to the Current Rooms list. Then open the Prefabs folder in the Project view and drag room1 from it to Available Rooms.
As a reminder, the availableRooms
property in the GeneratorScript is used as an array of room types that the script can generate. The currentRooms
property is room instances that are currently added to the scene.
This means that availableRooms
or currentRooms
can contain unique room types that are not present in the other list.
Here is an animated GIF demonstrating the process. Note that I’ve created one more room type called room2, just to demonstrate what you would do in case you had many room Prefabs:
Run the scene. Now the mouse can endlessly fly through the level.
Note that rooms are appearing and disappearing in the Hierarchy while you fly. For even more fun, run the scene and switch to the Scene view without stopping the game. Select the mouse in the Hierarchy and press Shift-F to lock the scene camera to the mouse. Now zoom out a little (Use the scroll wheel, or hold Alt+right-click, then drag). This lets you see how rooms are added and removed in real time.
Animating the Mouse
Right now the mouse is very lazy. It doesn’t want to move a muscle and simply lets the jetpack drag it on the floor. However, the price of jetpack fuel is quite expensive, so it is better for the mouse to run while on the ground.
To make the mouse run, you’re going to create an animation and modify the MouseController script to switch between animations while on the ground or in the air.
Creating Animations
Click the disclosure triangle beside the mouse_sprite_sheet to display all of the mouse animation frames.
To work with animations, you will need to open the Animation window, if you don’t have it opened already. Choose Window ▸ Animation to open the Animation view.
Place it somewhere so that you can see both the Animation view and the Project view. I prefer placing it on top, next to the Scene and the Game views, but you can place it anywhere you like.
To work with animations, you will need to open the Animation window, if you don’t have it opened already. Choose Window ▸ Animation to open the Animation view.
Place it somewhere so that you can see both the Animation view and the Project view. I prefer placing it on top, next to the Scene and the Game views, but you can place it anywhere you like.
Before you create your first animation, create an Animations folder in the RW directory in the Project view and make sure it is selected. Don't forget that most of new files in Unity are created in the folder that is currently selected in the Project view.
Next, select the mouse GameObject in the Hierarchy, since new animations will be added to the most recently selected object in the Hierarchy.
In the Animation window, you will be prompted to create an Animator and an Animation Clip to begin. Click Create and name the first animation run. Create a second clip called fly by selecting [Create New Clip] in the dropdown menu at the top left corner, to the left of the Samples property.
Note the three new files created in the Project view. In addition to the two fly and run animations, there is also a mouse animator file. Select the mouse in the Hierarchy. In the Inspector, you will see that that an Animator component was automatically added to it.