Quick viewing(Text Mode)

Independent Game Development with Unity Game Engine

Independent Game Development with Unity Game Engine

Independent Game Development with

Niko Jylhä

Master’s thesis December 2018 Degree Programme in Information Technology

ABSTRACT

Tampereen ammattikorkeakoulu Tampere University of Applied Sciences Degree Programme in Information Technology

Niko Jylhä

Independent Game Development with Unity Game Engine

Master’s thesis 62 pages, appendices 0 pages December 2018

"As far back as I can remember, I always wanted to be a gangster" is the opening line of the movie Goodfellas by Martin Scorsese, 1990 and as my opinion it’s one of the greatest in movie history. For me as a person that could be translated to "As far back as I can remember, I always wanted to be a game developer". When me and my brother got Commodore 64 back in a day for Christmas present it wasn’t enough to just play the games I wanted to learn how to make those space ships to fly and monsters to move.

But what does it mean to be a game developer? And to be more specific a “independent” one? How easy it is to start creating games? Is it possible to make money with games when there are thousands of games around?

Goal of this thesis is to share some light on those questions.

Theory part will focus on questions like, what “Independent game developer” means? What do you have to consider when creating games? How many independently created games are there and what kind of tools to create games?

Hands on part will focus on studying Unity game tool. Goal is to implement of game called Tapper and to study basic concepts of game, moving things around, like player and enemies and collision detection.

Key words: independent, game development, unity 3d, , xbox,

3

TABLE OF CONTENTS

1 Introduction ...... 6 2 Independent game development ...... 8 2.1 What is independent game development?...... 8 2.2 releases ...... 8 2.2.1 Steam Spy - PC ...... 8 2.2.2 , and Playstation 4 ...... 9 2.3 How to become independent game developer ...... 10 2.3.1 Game design ...... 10 2.3.2 Level design ...... 12 2.3.3 Marketing ...... 14 3 Game Development Tools ...... 16 3.1 Microsoft XNA Game Studio/MonoGame ...... 16 3.2 GameMaker: Studio ...... 16 3.3 Studio ...... 16 4 Unity – Game Engine ...... 17 4.1.1 Learning the Unity ...... 17 4.1.2 Unity Asset store ...... 19 5 Tapper game ...... 21 6 2D Game Development with Unity ...... 22 6.1 Creating the 2D project ...... 22 6.1.1 Creating the scene ...... 24 6.1.2 Scene background ...... 25 6.1.3 Automatic scaling...... 26 6.2 Player object ...... 27 6.2.1 Player movement points ...... 28 6.2.2 Canvas ...... 29 6.2.3 Moving the ...... 31 6.3 Enemy (aka customer) objects ...... 37 6.3.1 Enemy objects ...... 37 6.3.2 Spawning the enemies ...... 38 6.3.3 Moving the enemies ...... 41 6.4 Collision system ...... 43 6.5 Serving the drinks ...... 48 6.6 Ending the game ...... 53 6.6.1 Restart game button...... 53

4

6.6.2 Collision event to stop enemy spawning and to show Restart button ...... 55 7 Final words ...... 60 REFERENCIES ...... 62

5

LIST OF ABBREVIATIONS

XBLA Xbox Live Arcade – Microsoft’s game download service for Xbox 360. Steam distribution channel owned by Valve Corpora- tion. NES Entertainment System AAA or triple A “In the , AAA (pronounced "triple A") is a classification term used for games with the highest develop- ment budgets and levels of promotion. A title considered to be AAA is therefore expected to be a high quality game and to be among the year's bestsellers.” (Wikipedia) Apple App Store Apple video game distribution channel for IOS platforms iPh- one and iPad. Google Play Googles video game distribution channel for Android devices.

6

1 Introduction

Minecraft, Legend of Grimrock, World of Goo, Limbo, Fez, , Hotline Miami and Braid, just some of the names of the independent game development success stories. They all have been developed by individuals or small group of people in a way called indie game development.

Independent game development is a way for a person or group people to independently create games usually with small budgets. Now days game development tools like Unity and digital distribution channels like Steam offer developers’ easy way to start developing games. But starting is just the beginning the journey.

Purpose of this thesis is to study the what is indie game development and to learn how to create games using Unity Game Engine.

Objectives are: • to learn what independent game development means • popularity of indie games • what you have to consider when creating games • what game development tools are there to create your game • what distribution channels are there to publish your game • to learn how easy or hard it is to use Unity tool • implement level of Tapper game with Unity

Motivation for this thesis is the authors passion for video games and hopes of some day to publish his own game.

What is left out in this thesis is the actual publishing of the game. This side would be interesting to study in the future.

This thesis is presented in seven (7) chapters: • Chapter 1, introduction to this work. • Chapter 2, explains what independent game development is, shares some light about the popularity of indie games and explains some things you need to consider when creating games, like game design and marketing.

7

• Chapter 3, introduces to some of the game development tools out there. • Chapter 4, focuses on Unity Game Engine that was used in the “hands-on” part of this thesis. • Chapter 5, explains the Tapper game. • Chapter 6, is the hands-on part, where level of Tapper game is created with Unity tool. • Chapter 7, final chapter, talks about how things went, summary of goals set for this thesis and were they achieved.

8

2 Independent game development

2.1 What is independent game development?

Independent game development is a process where game is developed by a small group of people or even by one individual. Game budget is usually small, and it doesn’t neces- sarily have any publishers. Games are usually not released on physical copies, instead distribution channel for the game is usually digital portal like XBLA (Xbox Live Arcade), Steam, Apple App Store, Android Market Place, Nintendo eShop or some other similar channel.

2.2 Indie game releases How many indie games are there? Well, you could say that a “lot”. Exact figure is impos- sible to say because there isn’t just one list that lists them all. Although indie games are important strategy for companies like Nintendo, and Microsoft they don’t reveal lists of the indie games and line of “independent” is not always so black and white. For PC platform Steam Spy web site is probably best place to look for information but for other platforms like Xbox it’s a bit harder. Just to get the idea of popularity of creating indie games let’s have a look at two platforms PC and Microsoft Xbox using Steam Spy statistics and googling.

2.2.1 Steam Spy - PC Steam by was released in 2003 for PC. Steam is digital distribution platform for video games [https://en.wikipedia.org/wiki/Steam_(software)]. Steam Spy [steamspy.com] is a web site that collects sales statistics about the games sold in Steam. From 2003 to 2017 there are almost nineteen thousand games released and around twelve thousand of them are categorized as “indie” games. Although listed games don’t cover those games that are not sold in Steam (For example, those that are sold only in Xbox Live are not listed) it gives good picture about the popularity of creating indie games. In the early years, from 2003 to 2006 only around twenty indie games were released. It seems that after the 2010 number of releases slowly start to grow until 2013 it jumps to three hundred and the next year 2014 it’s almost thousand games. Between 2015 to 2017 its over ten thousand games.

9

Steam Spy - Indie games released per year 6000

5000 5120

4000

3377 3000

2000 2109

1000 984

183 300 0 100 2003 2005 2007 2009 2011 2013 2015 2017

FIGURE 1 - Steam PC indie game releases

2.2.2 Xbox 360, Xbox One and Playstation 4

Finding statistics for Xbox 360, Xbox One and Playstation 4 indie games is a bit harder. “Googling” revealed two sources that were quite useful. For Xbox 360 good place was Xbox market place US [https://marketplace.xbox.com/en-US/Games/XboxIndieGames] although I notice that some flaws in this list; some indie titles like Braid and Super Meat Boy were missing and listed games start from 2008 even though Xbox Live Arcade (XBLA) service was released for Xbox 360 late 2005. Xbox 360 has been a very popular platform for indie developers, one reason for that is the Microsoft has been supporting indie game development right from start of the Xbox 360 with its Xbox Live Arcade service. Microsoft has closed its indie program so it’s no longer possible to develop indie games for Xbox 360 and developers have moved to newer platforms [https://www.eurogamer.net/articles/2017-09-08-xbox-live-indie- games-officially-closes-29th-september]. For Xbox one and Playstation 4 I found a web site that lists released indie games. [https://www.finder.com.au/gaming/the-complete-list-of-indie-games-on-xbox-one, https://www.finder.com.au/gaming/playstation-4-indie-games]. Interesting comparison

10 between these systems is to notice that first years they have quite similar number of re- leases but in the year 2017 Playstation 4 took a jump of almost two hundred games above Xbox One.

XBox 360/One and Playstation 4 indie games released per year 900 834 800 719 700 572 600 548 500 386 400 394 300 183 166 149 162 200 94 52 144 140 100 48 33 3 70 0 9 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017

XBox 360 XBox One PS 4

FIGURE 2 Xbox 360/One and Playstation 4 indie game releases

2.3 How to become independent game developer

How to become indie game developer? Is the answer something simple like get some game development tool and start doing the game? Simple answer could be Yes but to become a good (and hopefully successful) indie developer you must consider different aspects of game development. It’s not enough that you can write code there also aspects like game design, level design and marketing to consider and of course you have to have some selling idea of the game.

2.3.1 Game design

Game design is a concept of the game. It defines what the game is all about, what is done in the game, what are the rules of the game, how it’s meant to be played. If the game design is not good, it doesn’t matter how nice looking your game is. Good game design is what keeps the players playing your game. In big games, game design can also refer to

11 the theme or story of the game and in smaller “simpler” games like racing games it could refer to how the game is played.

Game design is an iterative phase, you start with an idea of the game and iteration by iteration throw some ideas to the game, keep the good ones and throw bad ones away. How can you tell, what ideas are good and what are bad? For some ideas you probably don’t know until you get some feedback from players who are actually playing your game.

Design should take into account the platform where the game is meant to be played. If the platform is a mobile device, maybe take advantage of the special functionality it offers like location detection or motion tracking?

In the indie scene, good game design is important, especially for one reason; budgets are much smaller in indie games, so you may not have time or money to create amazing graphics and sound track. On the other hand, “amazing graphics” is relative thing. What some consider beautiful, like now popular 8-bit graphics, looks horrible for some people. Indie game design should try to introduce something surprising or innovative to the player. Like in game Braid (Jonathan Blow, 2008, XBLA) which basically is just a plat- former game like Super Mario has one speciality, which is the possibility to manipulate time. This meant that player could rewind the game anytime they want to. When the player drops in to a hole and dies, she or he can just hit the rewind button to go back and try again. Time manipulation was not the first time to see in a game (e.g. Prince of Persia – Sands of time, Ubisoft, 2003 had it) but it was the essential feature of the game, so the game design was based on this game play. One example of game design where game theme plays a big role is Hotline Miami (Den- naton Games, 2012, Windows). When you first look at this game it seems like an ultra- violent top-down shooter game but its visual style and specially soundtrack is all from the 80’s, like Miami Vice. Jonathan Blow, the creator of game Braid at his speech at Game Developer Conference 2011 - Truth in Game Design, talks about methods he used when he designed the game. Game gives player ability to reverse time, so he asked questions like “What happens when you give the player unlimited ability to reverse time?” (Time index 23:50). Next step was to implement the code that answers that question. When answer to this question can be seen in the game, it can show some things that could not be for seen as an answer to this question, which raises new questions and you can ask another question like “…what if

12 we make some objects immune to the players ability to reverse time?”. Continuing this process of asking question, implement the code and asking new questions brings large volume of questions and answers. Mr. Blow brings out important point that answers were not generated by the developer they were generated by the system corresponding to the asked questions which leads to the conclusion that some way game designed itself. “Be- cause there were so many answers (generated by the system) next step was to analyse them and clean them up so that they could be best appreciated by the audience of the game.” Johnathan also talks about that game design philosophy of being open to what is here, seeing what is available and observing things. This could be explained in way that game design is not just that, you have an idea or blue print of what game should be and you dictate things that come and answer the questions yourself. Instead you should ask the questions and let the system answer the questions in other words express itself. Designer should be an observer of things and see things that are interesting.

2.3.2 Level design

Level design basically is just what it sounds like. It’s a process of designing “levels” in a game. But what is “level”? It could be stages in Mario Bros or Braid (platform games) or environments in Halo multiplayer maps or missions and goals in Call of Duty games. As can be seen “level” isn’t just a simple concept. Depending of the game, level can mean different things and it means that to make a good “level”, level designer must have a solid understanding of the game, its gameplay, story, mechanics, places, and so on.

So, what would be a good “level”?

Simplicity Jonathan Blow the creator of game Braid at his speech at Game Developer Conference 2011 - Truth in Game Design, talks about “Simplicity” design methodology he used when designing puzzle game Braid. Simplicity didn’t mean that the level is simple to resolve (and if you try the game Braid you understand that isn’t the case). He realized that when designing Braid, he wanted to make levels simpler and simpler so that they would, for example be easy to navigate and goal of the level is clear. Complications in a level were just obscuring the puzzle. Simplicity left more space for the actual puzzle.

13

Another interesting level design decision in this game Braid is that you can progress to the next level without completing all the puzzles in one level. If one level is too hard, just progress to the next and come back to the uncompleted level later. But not to make things too easy to complete the whole game, you have to solve all the puzzles in every level, before you can progress to the final level.

Rewarding There are different ways to reward player on doing something, new skill level, in-game or completing the level could be a reward itself. Whatever the reward is, it should be something tangible so that it gives the player feeling of achievement.

Role playing games like Deus Ex: Human revolution or Fallout 3 are some examples of how to reward player with new skills. When quest is completed it gives player new skill points which can be used to improve players’ abilities.

Diablo games give player in-game items in other words “loot” like sword, shields, magic potions, etc. from concurred enemies and this loot gets better while you progress in a game, also this loot can be traded for better loot at stores.

David Braben and Ian Bell, the creators of game Elite (1984, Commodore 64, PC, Am- strad, Apple II and other computers of that time) explained their thoughts off reward in Inside Game Design (Simons, Ian). Game has a basic concept of fly around space, shoot other spaceships and avoid being shoot at. So how to make the player interested and play- ing the game? They didn’t like the idea of score, so they came up with money and how to make money? Well, you have trade, buy stuff cheap and sell for profit. When you earn money, you can improve your ship. This keeps player interested in trading which leads to money and money can be traded for improvements which is reward or achievement.

Challenge/Difficulty When comparing difficulty or challenge of the 80’s to 90’s video games to the modern video games, there is a general opinion that games back then gave player more challenge. In many cases that may be true but one thing to consider is that modern games have different design philosophy. When considering the starting point of retro games, they don’t necessary give player much instructions about how to play the game or what to do. So, they weren’t necessary very approachable games. One example would be there

14 weren’t any tutorial levels, automatic maps or hints and tips like modern games usually have, which makes them easier to approach. On the other hand, “problem” for the modern games is that they tend to hold players hand too much. They just don’t tell the player “go from place A to B and kill the bad guy” like “old” games, they say “start from place A and to get to place B, you must first go to the room D and turn the switch X which turns the elevator power on, then take to elevator to floor 2 where you find the place B”. In a way this “hand holding” has taken the joy of discovery from the players. It is said that “normal” difficulty level in modern games was “easy” in old games. One reason for this “hand holding” and easy difficulty is that big companies that make “triple A” games, makes them with big budgets. Big budgets mean that game needs to sell a lot and if the game is easy to approach and isn’t too difficult, player keeps playing it and probably will buy a sequel. Indie scene has given the game developers change to take step back to the old games when it comes to difficulty of the games.

2.3.3 Marketing

Apple App Store and Google Play each have over one million apps and roughly 20 to 30 percent of those are games. So just making a game and uploading it to store isn’t enough for the game to get attention in the game market. Emmy Jonassen at his speech Konsoll 2013: Marketing Indie Games on a $0 Budget says that “95 % of indie game are not profitable” and “80% operate at a loss”. So, there is great change that, without any marketing indie game developer will go in to those per- centages and the game will disappear in the oblivion of app store. This means that game developers can’t neglect the marketing aspect. But what are the possibilities for indie game developer to promote the game, if budget for marketing is small or even ?

Start marketing early Most of the games sales are made in the first weeks or even days after it has been released so game must have some kind of “hype” before that. To make the hype public has to have knowledge of the games existence. Good point to start marketing is when the game has something good enough to show to the public. This could be some screenshots of the game, story line, or playable demo. Whatever it is, it should be given some thought before

15 publishing it. One example would be art work, which is still in the development phase (done by the and not by graphics designer), are they worth publishing? Are they good enough to get public interested? Probably not…

How to start marketing the game? One place to start marketing the game is social media. Facebook, Twitter, Google+, In- stagram, YouTube, etc. all good places to start the campaign. Whatever the place it needs some active involvement like a blog and steady updates to keep the public interested. Updates to the blog should not all just be some technical/clinical stuff about the game. It needs to tell something personal about the developer themselves (like personal struggles) so that the readers get to know the person behind the game. Indie Game – The Movie is a good example (although it’s a little bit more than just a blog) where the audience learns about the creators of the game Braid, Fez and Super Meat Boy. Another thing about the updates is that it needs to have some major points like trailers or playable demos. Another place would be a concentrated web page but that needs some social media mar- keting before that so that the public learns about the existence of the page.

16

3 Game Development Tools

Now days it is relatively easy to start creating games (creating good games is another thing…). Instead of building game from scratch or creating game engine, there are many free game development tools that offer tools for creating 2d or 3d games. Many of them support cross-platform development so you can easily export same game to different plat- forms.

3.1 Microsoft XNA Game Studio/MonoGame

Microsoft XNA Game Studio is a programming environment for Microsoft Visual Studio. It provides framework and tools to create games for Xbox360 consoles, Windows Phone and Windows PCs. Current version of XNA Game Studio is 4.0 and since Microsoft has announced that it’s not going to release future versions of it but MonoGame which is an open implementation of XNA will continue to support it. Popular indie games created with XNA Game Studio includes titles like; platformer Fez (Polytron Corpora- tion, 2012), action role playing game Bastion (Supergiant Games, 2011) and Dead Pixels (CSR-Studios, 2012).

3.2 GameMaker: Studio

GameMaker: Studio (YoYo Games) is a game development environment targeted for novice who don’t have much experience on programming. It provides drag and drop system to action sequences, sandboxed scripting language and cross-plat- form development. One of the best known indie game created with GameMaker is Hotline Miami (, 2012).

3.3 Adventure Game Studio

Adventure Game Studio (Chris Jones, 1997) is game development environment mainly to build graphical adventure games like classic LucasArts games and Monkey Island. Actually, some of the old adventure games has been remade with AGS like Maniac Mansion, Kings Quest and Space Quest.

17

4 Unity – Game Engine

Unity is multiplatform game development engine, currently it supports over 17 different platforms like Windows, Xbox (360 and One), iOS, Android and Windows Phone. It gives tools for creating 2D and 3D type of games. Examples of popular games made with Unity are Cities Skylines (Colossal Order, 2015), Ori and the Blind Forest (Moon Studios, 2015) and (, 2015)

4.1.1 Learning the Unity

Good place to start learning Unity3D is to go to their web site unity3d.com. There are lot of tutorials, examples, videos and live sessions to get you started.

FIGURE 3. Unity tutorials

18

FIGURE 4 Unity 2D lessons

FIGURE 5 Unity Community

19

FIGURE 6 Unity in YouTube

4.1.2 Unity Asset store

Unity Asset Store is place where you can find readymade components like 3D models, textures, scripts and animation tools for your game. Some of them are free and some not. Anyone using Unity can submit their creations to Asset Store and set their price or set them as no charge. Each sale gives submitter 70% cut of the sale. These assets or addons can ease the pain of creating all by yourself.

20

FIGURE 7 Unity Asset Store

21

5 Tapper game

Tapper (or Root Beer Tapper) is an arcade game originally released in 1983. Different versions of the game have been released for platforms like Nintendo Entertainment Sys- tem (NES), Commodore 64 and modern consoles like Xbox360. Goal in the game is to serve beer, collect empty mugs and tips. Customers are moving towards the bartender and when player serves them a beer they move out. If player fails to serve beer on time and customer reaches the end of the bar table, it grabs the player and toss him out of the bar which results as loss of life. When enough lives are lost game ends.

FIGURE 8 Tapper game

(http://en.wikipedia.org/wiki/Tapper)

22

6 2D Game Development with Unity

Unity offers the tools to create basically any kind of game, but this hands-on part of this thesis will focus on the idea of the Tapper game. Goal is to learn some basic concepts of Unity tool like the meaning of scene, scaling, canvas, prefabs, interacting with the game, collision detection and enemy spawning.

6.1 Creating the 2D project

Unity has a support for 2D and 3D projects. Unity project can be marked as 2D project which sets default settings in editor and views to 2D mode.

FIGURE 9 Unity Project Wizard - 2D mode selected

When scene view is set in 2D mode movement is limited to X and Y axis when in 3D mode movement would also be possible in Z axis.

23

FIGURE 10 Scene view in 2D mode

FIGURE 11 Scene view in 3D mode

24

Editor settings have default behaviour mode selection which can be set as 3D or 2D. When new 2D project is created then editor settings already have 2D mode selected. Ed- itor’s behaviour mode can be changed to 3D even when creating 2D project. Behaviour mode 2D means that when new scene is created, default camera is created with projection Orthographic and size 5. Also, it means that when new image is imported it has texture type Sprite instead of Texture.

FIGURE 12 Editor settings

6.1.1 Creating the scene

Game creation starts by creating the first level which in this case will be a bar. Action in the scene happens in one screen so we can create the scene by creating and importing one sprite image to the Unity editor. Importing image to Unity is very simple, just drag and drop the image to editor. Hard part is to draw the actual image. To get started with the game development we can create the first version of the scene image by taking some Tapper game image from the Internet and modifying it a bit with Paint or Photoshop so that it fits our needs and use that for now.

25

FIGURE 13 Scene 1 background image imported FIGURE 13 shows imported image and its information in the Inspector view. In the Game view, aspect ratio has been set to 16:9 which is the common ratio for mobile phones. Basic folder structure has been created under Assets and it contains folders _Scenes, Sprites and Scripts.

6.1.2 Scene background

Putting the background to the scene is done by dragging the image to the scene view. After it’s done, image is shown also in the hierarchy view. When image is selected in the hierarchy view its information like position is shown in the Inspector view.

Game is designed to be played on mobile phones with landscape orientation and to make game support different screen sizes we need to make the image scale automatically ac- cording to devices screen size. Limiting the orientation of the game to landscape can be done from the build settings.

There are different ways to create script in Unity, one way is to add script component to the image from the Inspector view. One thing to notice is that by default script files are

26 created at the root level of Assets folder but we can drag and drop it to our Scripts folder. Once the script file has been created it can be opened in MonoDevelop or Visual Studio editor.

FIGURE 14 Background with Script component “ImageRescaler”

6.1.3 Automatic scaling

Game is meant to be run on mobile devices so there is no fixed screen size, so we must do some automatic scaling for images. This scrip is added to the background so that it effects all other images inside it like our bartender which is added later.

27

using UnityEngine; using System.Collections;

public class ImageRescaler : MonoBehaviour {

void Awake() { print ("--ImageRescaler.Awake"); //Get reference to the sprite renderer which displays images on Unity SpriteRenderer sr = GetComponent(); if (sr == null) return;

//Scale the object where this script is attached to its original size. transform.localScale = new Vector3(1,1,1);

//Calculate width and height of the image float width = sr.sprite.bounds.size.x; float height = sr.sprite.bounds.size.y;

//Calculate height and with of the screen float worldScreenHeight = Camera.main.orthographicSize*2f; float worldScreenWidth = worldScreenHeight/Screen.height*Screen.width;

//Scale image width Vector3 xWidth = transform.localScale; xWidth.x = worldScreenWidth / width; transform.localScale = xWidth;

//Scale image height Vector3 yHeight = transform.localScale; yHeight.y = worldScreenHeight / height; transform.localScale = yHeight; } } Figure 15 ImageRescaler

6.2 Player object

Our hero of the game is a bartender. Bartender is a simple game object that consists of Sprite Renderer. Bartender is created from the Game Object menu and selecting Create Empty. To our new game object, we just specify some name and select the bartender sprite in the Sprite Renderer. It doesn’t matter where this game object is added on the screen because it will be moved programmatically around movement points.

28

Figure 16 Our lonely hero

6.2.1 Player movement points

Player will be moving between four static points. Each point is located at the end of bar counter. These points are specified by creating empty game objects from the Game Object menu and selecting Create Empty. Once game object is created it is first located and shown in the Scene view at the position of X = 0, Y = 0 and Z = 0. From there they need to be moved to their correct location. Important thing to notice is that, because the back- ground is scaling automatically these points need to be moved in the Hierarchy view under the background image so that these points stay at their correct locations when the background image scales. FIGURE 17 Player movement pointsshows player movement points presented with stars (these stars are just presenting purposes, they will be re- moved).

29

FIGURE 17 Player movement points

6.2.2 Canvas

Once the movement points have been defined we need to make the player move between these points. For that we first need buttons which will move player up and down.

For UI components we will use Canvas which is a new feature introduced in the Unity version 4.6. Canvas is a root component for all UI elements like buttons and scene can have multiple canvases. Canvas has three different render modes which define how UI elements are drawn on the scene. Render modes are Screen Space – Overlay, Screen Space – Camera and World Space. In the Overlay mode canvas will overlay the scene and all UI elements will be drawn on top the screen also the canvas fills the scene auto- matically. Canvas will resize automatically if the screen size changes, so we don’t have to worry about the scaling like we had to when creating the scene background image. Render mode Camera is similar to overlay mode except that in this mode Canvas is ren- dered by a specific camera in the scene and this allows camera specific settings to be applied in the canvas.

When button is created it will also create canvas if it hasn’t been created already. Button has a two required elements Image script and Button script and optional Label element which can be removed if the button doesn’t need any text. Buttons image element can have some specified image which is shown as button. Button script defines what happens

30 when the button is clicked. One thing to notice is that in the Scene View Canvas is shown quite large but in the Game view and when the game is run canvas is resized and the buttons can be seen at their correct places.

FIGURE 18 Movement buttons in the Scene view

FIGURE 19 Game running. Buttons showing at their defined locations

31

6.2.3 Moving the player character

Now that the canvas and the movement buttons have been created it is time to make the player move.

In the first step, player image is first imported to the Assets view and from there it is drag and dropped to the scene. In the hierarchy view, it is located at the root level. Next step is to attach script to the buttons that handles the player movement.

For the movement script we create empty game object, rename it to MovementController and attach script to it.

Public variables and initialization

First in the script we define two un-initialized public variables. Declaring these variables public makes it possible to set their initial values in the editor view.

// The player game object (e.g. image) reference. public GameObject playerImage;

// The player position objects array. public GameObject[] playerPositions;

FIGURE 20 playerImage and playerPositions variables in the editor view, un-initialized.

32

First variable playerImage is GameObject type that will be initialized with our player image. Initial value for it is given by drag and dropping game object tapper_player from the Hierarchy view over the empty box in the Player Image section in the Inspector view. Other variable playerPostions is an array of GameObjects that will hold our player move- ment positions game objects. Initial values for it is given by drag and dropping game objects PlayerPoint1, PlayerPoint2, PlayerPoint3 and PlayerPoint4 from the Hierarchy view over the Player Positions text.

FIGURE 21 Initialized playerImage and playerPositions variables

Public methods and button onClick() action

Next thing to do is to define some variables and public methods that will be use in the actual movement:

// Movement direction up or down. private enum EMovementDirection { UP, DOWN };

33

// Static variable that keeps track of the current position in playerPositions array. private static int positionInArray = 0;

// Moves player one step up in the positions. public void MovePlayerUp() { MovePlayer(EMovementDirection.UP); }

// Moves player one step down in the positions. public void MovePlayerDown() { MovePlayer(EMovementDirection.DOWN); }

MovePlayerUp() and MovePlayerDown() are just simple methods that define the move- ment direction and call private method MovePlayer() that will handle the actual move- ment.

Public methods can be set to execute on button click. This is done in the Inspector view. Button has a On Click() Event component where can be selected which script and method to call when button is clicked. Button Up is set to call MovementController.MovePlay- erUp() method and Button Up is set to call MoveMentController.MovePlayerDown() method.

FIGURE 22 “Button Up” - Button On Click() component.

34

FIGURE 23 “Button Up” - Just after ‘+’ has been clicked. No script or method selected.

FIGURE 24 “Button Up” - MovementController script selected and list of methods.

35

FIGURE 25 “Button Up” - MovementController.MovePlayerUp method selected.

36

using UnityEngine; using System.Collections;

public class MovementController : MonoBehaviour {

// The player game object (e.g. image) reference. public GameObject playerImage;

// The player position objects array. public GameObject[] playerPositions;

// Movement direction up or down. private enum EMovementDirection { UP, DOWN };

// Static variable that keeps track of the current position in playerPositions array. private static int positionInArray = 0;

// On Start move player to the first position. public void Start() { print("--MovementController.Start: " + playerPositions.Length); MovePlayerToFirstPosition(); }

// Sets current position to the first position and moves player object there. public void MovePlayerToFirstPosition() { print("--MovePlayerToFirstPosition"); positionInArray = 0; MovePlayerToPosition(); }

// Moves player one step up in the positions. public void MovePlayerUp() { MovePlayer(EMovementDirection.UP); }

// Moves player one step down in the positions. public void MovePlayerDown() { MovePlayer(EMovementDirection.DOWN); }

// Moves player up or down depending on given parameter. private void MovePlayer(EMovementDirection movementDirection) { print("--MovePlayer: " + movementDirection); if (movementDirection == EMovementDirection.UP) { positionInArray++; } else if (movementDirection == EMovementDirection.DOWN) { if (positionInArray <= 0) { positionInArray = playerPositions.Length; } positionInArray--; }

if (positionInArray >= playerPositions.Length) { positionInArray = 0; } MovePlayerToPosition(); }

// Moves player to the current position private void MovePlayerToPosition() { print("--MovePlayerToPosition: " + positionInArray); playerImage.transform.position = playerPositions[positionInArray].transform.position; } } FIGURE 26 Full for MovementController

37

6.3 Enemy (aka customer) objects

6.3.1 Enemy objects

Game contains multiple “enemies”, so creating them all individually would be a pretty big job. Instead we create prefabs which are kind a like templates for the re-usable game objects. Prefabs are like normal game objects, they have components and settings. Instances of the prefab are basically copies of it, but they can override components and settings of the original and these overrides don’t affect each other. Changes that are made in the original prefab is reflected to all instances. Prefabs are simple to create. Like any other game object, we first create empty game object in the scene or in the hierarchy view. To our empty game object, we give it just a Sprite Render and assign picture to it. After this when we drag and drop it to Project views Prefabs folder and that creates our first prefab in the Prefabs folder.

FIGURE 27 - Enemy1 drag and drop to Prefabs folder After game object exists in the Prefabs folder it can be deleted from the scene or from the Hierarchy view.

38

6.3.2 Spawning the enemies

After enemy prefab has been created next step is to start spawning them. First step is to define enemy spawn points. Spawn points are created in a similar way as the player move- ment points were created, by adding empty game object in places were the enemies are spawning.

FIGURE 28 - Enemy spawn points

After the spawn points are created next step is to write a script that handles the actual spawning. EnemySpawner shown in FIGURE 30 is a script that spawns enemies in a ran- dom spawn points. After the game starts, EnemySpawner script starts spawning enemies in waves. It is possible to configure how many waves are spawned and how many enemies are in each wave, also it is possible to define time between each wave. For the clarity, script is attached to the empty game object and our enemy1 prefab is drag and dropped to the Enemies array shown in Inspector. Enemy spawn points are drag and dropped to Spawn Locations folder (FIGURE 29).

39

FIGURE 29 - Enemy spawner

40

using UnityEngine; using System.Collections;

public class EnemySpawner : MonoBehaviour {

// Locations where to spawn enemies public Transform[] spawnLocations;

// Enemy game objects public GameObject[] enemies;

// Time between each spawn public float timeBetweenWaves = 1.0f;

// Number of waves to spawn before stop spawning public float numberOfWaves = 5.0f;

// Number of spwaned enemies at each wave public float numberOfSpawnedEnemies = 3.0f;

// Delay before start spawning when game starts private static float SPAWN_DELAY = 2.0f;

// Delay between enemies. If two sequential enemies are spawned // at the same location this makes sure that they dont get spawned on top of each other. private static float DELAY_BETWEEN_ENEMIES = 0.25f;

// Use this for initialization void Start () { // Start couroutine StartCoroutine (doSpawning ()); }

private IEnumerator doSpawning () { // Wait a bit before starting spawning yield return new WaitForSeconds (SPAWN_DELAY);

Debug.Log ("--doSpawning");

// Current wave counter int currentWave = 0;

// Start infitive loop which will be stopped after all waves are completed while (currentWave < numberOfWaves) { Debug.Log ("--Start wave " + currentWave + ", " + Time.time); for (int i = 0; i < numberOfSpawnedEnemies; i++) { spawnEnemy (); yield return new WaitForSeconds (DELAY_BETWEEN_ENEMIES); }

currentWave++;

// Wait between waves yield return new WaitForSeconds (timeBetweenWaves); } }

// Spawn single random enemy at single random point private void spawnEnemy () { // Select random spawn point index int spawnPointIndex = Random.Range (0, spawnLocations.Length);

// Select random enemy GameObject enemy = enemies [Random.Range (0, enemies.Length)];

// Create instance of the enemy Instantiate (enemy, spawnLocations [spawnPointIndex].position, Quaternion.identity); } }

FIGURE 30 Full source code for EnemySpawner

41

Because we need to pause the code execution between waves and every enemy, spawning is done in a coroutine private IEnumerator doSpawning (). Coroutines are like functions but they have the ability to pause the code execution with yield. With yield it is possible to pause the execution for specified seconds (WaitForSeconds).

At this point when game is started our spawning script just creates enemies in these static points (FIGURE 31) and they are not moving so next step is to make the enemies to move.

FIGURE 31 EnemySpawner at work. Enemies have been spawned at four points, but they are not moving.

6.3.3 Moving the enemies

To make the enemy to move it needs two more components, rigid body and scrip. From the Inspector view using Add component we add Rigidbody 2D and new script named EnemyPhysics.

For the Rigidbody 2D it is important to set gravity scale as zero. That defines that the gravity is not affecting the object. If gravity scale is set to something other than, it would mean that the object would start falling when it is spawned (FIGURE 32).

Enemy physics script presents two public variables minSpeed and maxSpeed. Those var- iables are public so that it is easy to adjust movement speed from the Inspector view. Script is quite simple, it adds force to the rigid body of the enemy1 object and that makes it move (FIGURE 33).

42

After the rigid body 2D and script are at place we can try to run the game. Now the ene- mies are moving (FIGURE 34) but the movement never stops, so next step is to add some collision detection to it.

FIGURE 32 enemy1's gravity scale set as zero (0)

using UnityEngine; using System.Collections;

public class EnemyPhysics : MonoBehaviour {

// Minimum speed of the object. public float minSpeed = 1.0f;

// Maximum speed of the object. public float maxSpeed = 3.0f;

void Start () { // This is just to verify that min speed is never below 0.5 // Negative speed would make the object move backwards. if (minSpeed < 0.5f) { minSpeed = 0.5f; }

// Get rigid body object Rigidbody2D rb = GetComponent ();

// Set random speed between min and max speed float forceX = Random.Range (minSpeed, maxSpeed);

// Create force vector to present movement to right. // First parameter presents x vector and second parameter y vector. // Positive first parameter presents movement to right. Negative would be left. // Second parameter as 0 defines that it’s not moving up or down. Vector2 forceVectorRight = new Vector2 (forceX, 0);

// Add force to rigidbody. This makes the object to move. rb.AddForce(forceVectorRight, ForceMode2D.Impulse); } } FIGURE 33 Full source code for EnemyPhysics

43

FIGURE 34 Enemies are moving but the movement never stops

6.4 Collision system

Box collider First, we need to add Box Collider 2D component to our enemy1 prefab from the Inspector view (Select enemy1 from prefabs -> Add component -> Physics 2D -> Box Collider 2D). Box Collider 2D like the name suggests is a rectangle in a specific position with height and width. In our case position is the position where our enemy is. When added to the enemy1 the width and height of the box is automatically the size of our enemy1 sprite, but the size is not tided to that. Size of the box can be edited bigger or smaller.

44

FIGURE 35 Enemy with Box Collider 2D Now that the enemies have box colliders they would be colliding with each other also. This is not wanted so we need to add enemies to a specific layer and adjust project physics settings so that objects in this layer are not colliding with each other.

Layers Layers can be created from the from the Inspector view while enemy1 prefab is selected using Add Layer (FIGURE 36).

FIGURE 36 enemy1 prefab with specific layer

Collision matrix

45

Now that the enemies are in the Enemy layer we need to adjust project physics settings (Edit -> Project Settings -> Physics 2D) (FIGURE 37).

FIGURE 37 Project physics settings

From the collision matrix unselecting Enemy – Enemy checkbox sets the enemies not to collide with each other (FIGURE 38).

46

FIGURE 38 Project collision matrix

Reaching the end of the bar tables Enemies are now moving, and they have box colliders that react when they collide with other colliders. Next step is to add colliders at the end of the bar tables so that we can stop movement of the enemies. Starting with empty game object (GameObject -> Create Empty) four Edge Collider 2D components are added to it. Edge Colliders consists of line segments and it can be simple as straight line or more complex form like L-shape. Points of those four edge colliders are modified so that they locate at the end of the bar tables (FIGURE 39).

47

FIGURE 39 Edge colliders at the end of the bar tables

FIGURE 40 Game running. Enemies stop at the end of the bar tables because they hit the edge colliders For later purposes one more adjustment is needed for the colliders. In the Inspector view, using “Add tag” and “Add layer” they are tagged as “EnemyFrontCollider” and also added to the similarly named layer (FIGURE 41).

48

FIGURE 41 Enemy colliders marked with tag and added to the special layer

When enemy hits the collider, it could star some event like decreasing points or kill the player. In the original Tapper game when the customer reaches the end of the bar table it grasps the bartender, drag him through the table and player loses a life and when enough lives are lost its Game Over.

6.5 Serving the drinks

Now that we have some enemies moving and player has the ability to move the bartender next thing is to give the player ability to serve some drinks. To make this happen we can use the same methods that have been used earlier. First new brefab “Glass” is created with components Rigidbody2D, BoxCollider2D and two scripts. One script contains physics to make the glass move when instantiated and other for collision detection. For Rigidbody2D Gravity Scale is set to 0 to prevent glass falling from the screen. Also new layer “Glass” is defined.

49

Figure 42 Glass prefab Scripts for the glass prefab are pretty simple. First scrip makes the glass move when glass instance is created. What makes this script different from the EnemyPhysics which moves the enemy is the use of FixedUpdate() method and setting the glass objects velocity di- rectly. Unity documentation says that this method is not usually used which makes the EnemyPhysics way of moving better but for learning purposes we try this method. (https://docs.unity3d.com/ScriptReference/Rigidbody2D-velocity.html)

50

using UnityEngine; using System.Collections;

public class GlassPhysics : MonoBehaviour { private Vector2 speedLeft = new Vector2 (-3, 0);

//This function is called every fixed framerate frame, if the MonoBehaviour is enabled. void FixedUpdate () { // Set objects velocity every framerate. Note! this value is not usually set directly // but rather by using forces like in the enemy physics but for learning purposes lets use this for now. GetComponent ().velocity = speedLeft; } } Figure 43 Glass physics

Another scrip defines that if collision is made with enemy object it is destroyed. Also, the glass object itself is destroyed. Detection of enemy is just simple if -statement with check- ing of objects tag.

using UnityEngine; using System.Collections;

public class GlassCollision : MonoBehaviour {

void OnCollisionEnter2D(Collision2D coll) { print ("--Collision: " + coll.gameObject.tag);

//If hits enemy if (coll.gameObject.tag == "Enemy") { //Destroy self Destroy(gameObject);

//Destroy collided enemy Destroy(coll.gameObject); } }

Last step is to extend MovementController script with new public method ServeDrink (Figure 44) which instantiates glass object to the players position and to add new button “SERVE” (Figure 45) with “On Click()” event to call that method.

51

… // Glass prefab object that is served public Transform glass;

public class MovementController : MonoBehaviour { …

//Instantiate glass prefab object to the place where player is positioned public void ServeDrink () { Instantiate(glass, playerImage.transform.position, Quaternion.iden- tity); } … }

Figure 44 MovementController extended with ServeDrink() method

Figure 45 Serve button with OnClick event

52

Oh, and one more thing is needed. Collision matrix needs some adjustment. We don’t want our glass to make collision with the bar table end points. If it would collide it would stop the glass from moving (Figure 46).

Figure 46 Prevent glass from colliding with the bar table end points

Now all things should be in place and player has the ability to serve some drinks.

53

Figure 47 Some beers are served

6.6 Ending the game

When the enemy reaches the end of the bar table it means that player has failed and should result as a lost life and when enough lives are lost its game over. For now, we just stop enemy spawning and show Restart -button that can be used to restart the game.

6.6.1 Restart game button

First, we extend MovementController with simple public method that reloads Scene1 (Figure 48).

54

… using UnityEngine.SceneManagement;

public class MovementController : MonoBehaviour { …

public void RestartGame() { //Load Scene 1 SceneManager.LoadScene("Scene1"); } … }

Figure 48 MovementController extended with public method RestartGame()

Next we add UI button similar to Button Up/Down and set its OnClick() method to call MovementController.RestartGame(). Also, we give it a new script component and name it Restart (Figure 49).

Figure 49 New Restart UI button Restart script is simple script that hides the button on Start and offers public method to unhide it (Figure 50).

55

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;

public class Restart : MonoBehaviour {

Button restartButton;

void Start () { restartButton = GetComponent