Update Jan. 27th: info and link to non-commercial version of PlayMaker added.
Update Feb. 1st: A new chapter was added on re-creating Breakout. Have fun with it! Course was extended to more than twice the size.
This course is a gentle introduction to small interactive games like Flappy Birds or other classics. Instead of making a clone, we will only go through the game mechanics: flapping or jumping, gravity and collisions, using Unity Physics.
The graphics will be deliberately crude: a white capsule and a few boxes. There are no textures, sprites, sounds or particle effects. We encourage you to make something of your own.
You'll need to know the basics of Unity: creating GameObjects, navigating the 3D Window and adjusting components. We'll use the popular Playmaker extension from the Asset store, which is a visual coding system, providing a Finite State Machine implementation, requiring no custom scripting. We go through every step from scratch, although the final result can be downloaded as a package for you to study.
If you need help in setting up PlayMaker, you can start with the bonus chapter in the end, which also points you to a free non-commercial version of PlayMaker, if you are an educational user, but the regular version has regular sales on the Unity Asset Store, so pay attention.
So if you want to add some interactivity and make something fun, but don't know where to start, this is a good opportunity. And please share your results and make something unique.
Before we begin the course, we give a small demonstration what our final result will look like. It is crude and simple, but we create it from scratch. There is nothing to download, nothing to install, apart from PlayMaker.
This is not a fill-in-the-blanks course, which will get you a polished result, but which does not teach you much. Every step you do is your own and you can diverge from the example as much as you want.
What is this course about? What can you expect? What not?
We start with creating a new Unity project and adding the PlayMaker package. If you have not used PlayMaker before, head over the the Asset store: PlayMaker Package
While it is not free, it is often available at a discount.
In this lecture, we set up a few game objects: a capsule which will become our hero, a Directional light to see something and two quad mesh objects, which will act as floor and ceiling. We also set up the camera to be orthographic, rather than perspective, as to get a (fake) 2D look.
Position everything in the center of the world, so it is easier to navigate around.
PlayMaker adds Finite State Machines (FSM) to Unity. FSM define the behavior of objects. PlayMaker provides a visual approach to manage the states of objects.
The concept is straight forward:
Some useful tips:
Make FSM as small as possible. Simply describe in which different states a particular object can be. If an object has multiple behaviors, such as moving and shooting, you can define them in different FSMs.
If you need to maintain a score or health or inventory, define them as "Managers", which are often just empty objects with a few local variables. The managers do nothing special, but they react on usually global events.
Objects that are interactive in the scene get their own FSM. They don't keep a score or health or other information. They simple have their own behavior and will send a (global) event to the managers that will do the book keeping.
Now we are ready to get into action. We add an FSM (Finite State Machine) to our hero character and have him jump or flap whenever we hit a button or press the mouse.
Everytime we push the screen or press a key, an impulse force is applied which pushes him up. But by also adding a RigidBody component, the Physics engine will ensure that he falls down again.
In fact, our very basic game mechanics are ready at this point. But we'll continue a bit, off course.
The next step is reacting on our player hitting things.
We focus on the lower quad, which acts as a ground plane. By adding a FSM, we can check collisions against the player. The collision event ensures that only an object tagged "Player" will be detected and then emits a "global" event, to warn other FSMs that something was hit by the player.
That's all our ground plane needs to know.
The moving poles take a bit more effort to set up, but they are still fairly easy to create. We add two boxes, one "upper pole" and one "lower pole" and group them together by parenting them to an empty object, called poles.
Both poles get a copy of the FSM from the ground plane, as they also need to detect the player hitting the pole.
We'll add a new FSM, which will first move the poles to the far right (outside of the screen). They will also shift a bit up or down randomly, so the space between the two poles is always at a different spot.
And then they get into a moving state, where they simple move from right to left at a fixed speed.
Maybe you can slowly increase this speed over time?
And to clean up, they get removed or destroyed when they have passed the left side of the screen. This is simply done by checking the position and comparing it to a preset fixed value.
At the end, we also turn the Poles object into a Prefab, so it can be instanced afterwards whenever we need a new pole. All poles in the game are just copies of this one.
Some question about the physics setup of the game.
We set up an empty GameObject with two new FSMs to manage our game. The first FSM is the "Pole Spawner". This loops between the creation of a new pole (an instance or clone of the Poles prefab) and waiting for the next pole to be added.
As the poles take care of movement and hit checking, there is nothing else to do in the Pole Spawner.
However, to clean up when the player hits anything, we react on the global "player_was_hit" event and go to an empty final state, so no new poles will be added.
Ultimately, we need to keep track of a score. Our interpretation of the game simply compares the position of the Poles ("current_x") with the fixed value of -1. If we ever get that far, that means our pole has passed the player without being hit, so we can emit a message to increase the score. This is done by the Poles.
The actual score keeping is done in the second FSM that is attached to the Game Manager: our Score Manager.
This keeps the score as a whole number (integer) called "score" and also transforms this into a string. We'll use a GUI Text to display this string.
Whenever we receive the global "add_score" event, we will increase the score and display the new value.
Tip: This would be a good time to add a sound or particle effect.
But we also need to react on the global "player_was_hit" event and finish the game. This is done be allowing the user to press a "restart" button (but any click or key press will also do this).
That's it. We are ready to test. We also ensure that the hero is stopped at this point, by also reacting on this global event.
Tip: Maybe you can look at "PlayerPrefs" to store our maximum score?
How we organize our game with the Game Manager.
We briefly summarise what we accomplished and look to possible extensions. Be creative! Don't copy Flappy Bird, but make something completely different with the mechanics from this course.
This game is a recreation of a classic Breakout game: you move a paddle from left to right and try to catch a falling ball. By bumping the ball up, you can hit target bricks for points. When you get the final brick, you finish the level.
Here we show the end result we can achieve at the end of this Section.
First we create our paddle: a simple Cube. We react on key presses: the left and right arrows. Whenever one of those keys is held, we go to a moving left or right state.
The first attempt is straight forward, but we have to finetune it a bit, to allow moving from the moving left to the moving right state directly, as to allow an improved control over the paddle movement.
Otherwise, we would have to pass by the waiting state every time we change direction and we have to release the left button before we can start moving right.
The walls will be simple cubes. There is nothing to it.
The ball is a sphere. We add a Rigidbody to it, to make use of Unity Physics, but we don't use Gravity. Instead, we set the velocity of the ball in our FSM.
We use a Vector3 (an X-Y-Z direction) to define where the ball is moving. Whenever we hit an object, we get the direction of that object from the Collision Event, in the Normal, which is also a Vector3. This defines the perpendicular direction of the surface we hit.
We need to reflect our incoming direction (before the hit) with the surface to get our out coming direction (after the bump). Luckily for us, PlayMaker provides a simple "Reflect" operator which does exactly this.
At the end of this lecture, we already have the main game mechanics of our project in place.
However, when we miss the ball, it continues into an eternal void. We need to catch the ball with an invisible box. Upon collision, we can reset the level. A bit brutal, but this works for now.
And now we can introduce the target bricks: simple boxes, that also react on a collision with the ball. In fact, we use almost the same FSM as the reset box, but instead of resetting the level, we destroy the brick to remove it from the game.
When we hit a brick, we need to keep track of the score. We do this by defining a global event "add_score", which can be reused from the Flappy Capsule game, if we work in the same project.
Whenever a brick is hit, it emits this event globally. Nothing more.
Then we add a Game Manager object to track the score. It keeps track of the score with a "score" int variable, which is increased every time we receive an add_score global event.
The Game Manager is then responsible for displaying the score, by copying the score value in a string to be display as a GUI Text element.
Beware that at this point in the project, the game has no end...
The final task is keeping track of the score. We do this by counting all bricks. The easiest way to do so, is by adding a tag to the bricks and counting the tags at the start of the level (in the Start State of the Game Manager).
Now we can compare the actual score with the total required score, every time we receive an add_score event and if they are equal, we transition to a Finish State.
The make a clean end, we display a Restart GUI Button and also warn the other FSMs in the scene, so the paddle stops moving and the ball is cleaned up.
That's it. Our game is ready. Or ready enough, at least.
That is it. We finished the game. It's not perfect, but it is fully functional. Think about what you could do next: increase the speed over time? Add some special bricks with special features? Add a shooter to the paddle? Slowly move the bricks down? There is no limit to what you can create.
This video shows how to load PlayMaker into a new Project from the Asset Store. You do need a license, however. For non-commercial use, you can also order a free Student License of PlayMaker. This suffices for this course, but there is no option to use custom Actions with it.
While it is advised to create the whole game step by step, a Unity Package is also provided for your convenience, with the main levels and the prefab objects that are required. These packages are very small, but they give you the end result of each Chapter.
However, please adapt them to your own liking and style and do something original with it.
The video shows how you can add the Flappy package into your game but do this only after you have installed PlayMaker, or you'll get errors.
Thank you for taking this course. I really hope you enjoyed it and please stay in touch. Leave a message on the Discussion Board, leave an honest review or spread the word to other possible students. This really helps me continuing making new courses and improving the existing ones.
And if you have a question, do not hesitate to ask.
Stefan Boeykens is an architect-engineer from Belgium.
After graduation, he worked a few years as a professional architect, for several local offices, where he was involved in design, building permits, drafting, site supervision, visualisation and IT management.
At the end of 2000, he got the opportunity to return to his former university (KU Leuven), at the Department of Architecture, where he started teaching Computer Aided Architectural Design. Initially AutoCAD and 3D Studio VIZ, but step-by-step, he introduced SketchUp, Rhinoceros + Grasshopper, ArchiCAD, Artlantis, Unity, Processing and Cinema 4D. He completed a PhD on Building Information Modelling in 2007 and worked a few years as a post-doc, focusing on the use of BIM throughout the design process. He became familiar with a wide variety of IT skills: Windows, OSX, Linux, VBA in Excel, php, C++, Java/Processing, Autolisp and C # in Unity.
At the moment, Stefan is a part-time guest professor at KU Leuven, teaching primarily ArchiCAD, Grasshopper, Cinema 4D and Unity, where he has created several online video tutorials.
In parallel, he is working as a BIM specialist/consultant for D-Studio, a Belgian company focusing on BIM middleware and consultancy. He is a frequent speaker at BIM-related events and is actively involved in different professional working groups on BIM standardisation, including CEN/TC 442 (Europe) and TC BIM & ICT + CLUSTER BIM (Belgium).
He is father of three boys and enjoys reading, cycling, loosing time online and learning.
If he has some additional time, he likes to compose music, mainly focusing on guitar, but occasionally with vocals, synths and laptop drums.