Penny Pixel Platformer – Part 1 – Winning and Losing


Note: This tutorial is a work in progress. Please let us know if you have any comments. You might also want to see the Getting Started tutorial series to get a jump start on some of the features whilst this tutorial is completed.

This tutorial will build upon the Unity “Live Session: 2D World building w/ Tilemap & Cinemachine for 2D” platformer tutorial and show how you can use Game Framework to turn the tutorial project into a real multi level game ready for release.

In this first part we will look at recording collected gems along with winning and losing the level.

Initial Setup

For this tutorial we are using Unity 2017.3.

First download the tutorial project from https://oc.unity3d.com/index.php/s/VzImolXrvp3K2Q5, open in Unity and inspect the contents. The tutorial provides a platform environment, player and some collectible gems. It is highly recommended to view the underlying tutorial on how the sample was setup.

Next import Game Framework (Free or Extras Bundle) from the asset store into your new project. In this tutorial we will use some assets from the extras bundle as they provide a better match to the graphics style of the Unity tutorial, however you can quite happily use the free package with and use the provided graphics, or customise at a later time.

(Note: compile error (Extras Bundle only) due to CollectableGem Rotate script not using a namespace. Workaround – rename CollectableGem\Scripts\Rotate.cs to RotateCG.cs – same for class in the file. Note to self – add full namespace in Beautiful Transitions to work around this).

Open the scene Scenes/TilemapDemoComplete.unity. You will see two GameObjects in the Hierarchy named Grid. Delete the active one and enable the disabled one. Your scene, hierarchy and project should now look similar to the below:

Game Manager

The Game Manager helps manage global state about your game and remains active across all scenes. It is also where you can configure the basic structure of your game such as the number of levels and several other options. As such it is a key component that you will use in many of your games.

To the open TilemapDemoComplete scene, add a new gameobject (GameObject Menu->Create Empty), and rename this to _GameScope. We will use this game object to contain any components that will remain active across all scenes.

Add a GameManager component to _GameScope by selecting the _GameScope gameobject and then clicking the Add Component button in the inspector and selecting Game Framework->Game Structure->Game Manager (note: all Game Framework components are available this way so in future we will just give the path in the add component popup menu).

addcomponent

In the GameManager component that you just added, change the Level Setup mode to Automatic and Unlock Mode to Completion as shown below. At the moment we only have one scene, however we will revisit this option later so don’t worry about this for now.

We now have the basics for a game with a player (with 3 lives) and 10 levels where the first level will be unlocked at startup and new levels can be unlocked by completing the previous one. At the moment we only have one scene, however we will revisit this later so don’t worry about this for now. You can run the scene at this point, but you won’t see anything new. We will address that next.

Level Manager

The second thing that we need to setup is a Level Manager. LevelManager allows us access to information about the currently selected Level and also other state information such as number of seconds running, level high score etc. It also provides several conditions to automatically detect and show the game over window along with methods that we can call to indicate when we start and finish a level.

Add another new gameobject to the root and name it _SceneScope. We will use this to contain all generic components relating to the current scene.

Next add the LevelManager component (Add Component->Game Framework->GameStructure->Levels) to_SceneScope. Set the Auto Start property to True so that we ‘start’ the Level immediately (this could also be triggered by your own code through LevelManager.Instance.xx()). Set the Game Over When Lives Is Zero option to True also so the player loses the level when they runs out of lives.

<image>

Collecting Gems

The Unity tutorial lets you collect gems, however doesn’t implement any scoring functionality. We will use the Game Framework counter functionality to record how many gems we have collected. Game Framework defines several built in counters such as for score and coins, whilst also letting you add custom counters for your own purpose.

First we need to decide whether to add the collected gems to the player, level or both. This choice comes from how we want to use the collected items in our game. In this tutorial we will let the user win a level by getting to a ‘goal’, and so use gems as a type of currency to unlock new characters. For this reason we will add them to the player where they are automatically saved between game restarts. If we had wanted the player to have to collect a certain number of gems to complete a level we would have added them to the level where they are typically reset each time the level is started. Another possibility is to add them to the Level and then use the UpdatePlayerScore option on the GameOver dialog (described below) to only update the player if the level is won.

Collecting

Select the CollectableGem\CollectableGem prefab and add a Game Framework | Game Structure | Collision Handler component. To theWhen Entering A Collision section add the Player | Change Coins action. This will now cause the players total coins to be increased when a collision occurs. We could also trigger the particles and hiding of the gem through additional actions, however those are already handled by the GemBehaviour script so we won’t worry about that here.

<image>

Note: We are using ‘Coins’ to hold the ‘Gems’ count however that doesn’t really matter.
Note to self: use a custom counter for gems instead of coins to demonstrate that?

Cheating

We will display the collected gems shortly. To check things are working however we can use the cheat window. This allows us to view and play around with certain setting to aid in testing and verifying your game. Ensure the cheat window is shown (Windows->Flip Web Apps->Cheat Window) and then run your game. If you click the Player tab you should see that Coins is zero. Collect coins in the game and this counter will increase (note you might need to click another tab and then back to the player tab to update the display). You can also use the buttons to manually update values.

Display

Add a UI text to your scene root by going to GameObject Menu->UI->Text.

On the Canvas gameobject that was automatically created, change the Canvas Scaler UI Scale Mode to Scale With Screen Size so that the UI expands and shrinks with the screen and set the Reference Resolution to 1920 x 1080 to match a resolution with which we some of the dialogs are designed.

Rename the newly added text gameobject to TotalGems and anchor it to the top right by setting:

  • Rect Transform | All Anchors: 1
  • Rect Transform | Pos X & Pos Y: -5
  • Rect Transform | Width & Height: 0
  • Text | Alignment: Right
  • Text | Horizontal & Vertical Overflow: Overflow
  • Font Size: 50

Adjust the color and font as you see fit (we have used a white color and the KOMIKAX font from the Extras Bundle).

pausebutton

Finally to have the score updated add the ShowCoins component (Add Component->Game Framework->Game Structure->Player) onto the TotalGems gameobject to show the total number of coins (gems) the player has.

There is also a component ShowScore to show the players score, and then corresponding components under GameFramework | GameStructure | Level to show coin and scores gathered for a specific level.

Run the game and you should see that the display is now updated to reflect the number of collected gems. We will revisit some of the other options such as customising the text in a later section.

Game Over

Game Framework includes customisable Game Over prefabs. Drag a GameOver prefab into the root of our scene. You can either take the standard one from (\FlipwebApps\GameFramework\Prefabs\UI\ or \FlipwebApps\GameFramework\Themes\Minimalist\Prefabs\UI) or if you have the Extras Bundle installed then use one of the themed GameOver dialogs from (\FlipwebApps\GameFrameworkSamples\Themes\[Theme Name]\Prefabs\UI\). If using the extras bundles dialogs then be sure to enable the Beautiful Transitions integration (Window | Game Framework | Integrations Window) as the dialogs contain transitions and otherwise won’t show.

On the GameOver gameobject, deselect the Show Score checkbox as we are only using gems (coins) in this game.

To get the dialogs to work you will also need to add a DialogManager  component to _SceneScope (Add Component->Game Framework->UI->Dialogs). This provides generic functionality for managing and controlling dialogs.

Losing when all lives lost

As we earlier set on Level Manager that the game should be over when the player loses all lives. Run your game and in the Cheat Functions Window under the Player tab, use the lives buttons to decrease the number of lives. When the lives reach zero you should see that the gameover window is automatically shown.

If you click the retry button, you might notice a slight issue that the game over dialog shows straight away! This is because the players lives are saved and so are detected as zero immediately when the game starts (you can verify the current number of lives in the Cheat Functions window).

All parts of the API can be accessed through code, but the simplest way to reset the lives is to drag the Game Framework | Game Structure | Player | Set Lives component onto _SceneScope and select the Use Global Life Count option. Now when we re-enter our game the number of lives will be reset to the global default from Game Manager.

SetLives

Finally we want some way of actually showing the lives to the user in our game. There are a couple of components that will help us out which basically allow us to set this up however we want. They are under Game Framework | Game Structure | Player:

  • Enable Based Upon Number Of Lives – allows us to show one of 2 different gameobjects based upon whether the player still has available a given life.
  • Create Lives Icons – creates a given number of instances of a prefab (representing a life) based upon the total number of lives. If the prefab contains the above Enable Based Upon Number Of Lives component then its life number will be automatically set.

There are 2 standard prefabs (LifeIcon and Lives) that make use of the above components. These lie under GameFramework\Prefabs\GameStructure\Player and there are both standard and themed versions available. As mentioned above we can create n LifeIcon prefab instances manually (1 for each life the user can have), or use the Lives prefab to automatically set them up.

On our Game scene, drag the Lives prefab under the Canvas gamebject, set Pos X  to and Pos Y  to -55 to position the prefab to the top left of the display. Run the game and you should now have life icons that update when lives change.

Similar to how we collected gems we can setup tiles or add enemy sprites that automatically cause us to lose lives. We will get back to this later.

Winning when reaching the goal

We will let the player win the level when they reach a specified point. Save the below sprite into your projects Sprites folder and make sure that the Texture Type is set to Sprite (2D and UI).

Drag the sprite into your scene and set it’s position to 11.7, 1.35, 0. To the same Sign gameobject add a Box Collider 2D component select Is Trigger. Add a Collision Handler component (Game Framework | Game Structure) and under When Entering a Collision add the action Level-> Win Level.

<TODO: Add Audio>

Run the level again and you can now win by getting to the goal.