Adventures in Unity – 1.3 Initial GSM

Official_unity_logo

 

#1 What would I ideally like to achieve by the time I finish working today – Build a basic GSM incorporating a title and game over screen, displaying players score. Allowing games to end and be restarted.

#2 What’s the minimum I’d like to achieve by the close of play – Build a basic GSM incorporating a game over screen, displaying players score. Allowing games to end and be restarted.

 


 

With the game in it’s current state, there’s still a lot of work to do – I decided, for the moment, to stop developing the game-play and work on the GSM instead.

This was partly because I think the game itself is getting some shape (even with such little actual code in place), whereas the GSM & how I was going to implement it was still very much undefined in mind.

It was also partly because when testing the game I didn’t want to have to keep stopping & starting the test environment every time the player went off screen – It’s gets old fast.

Partly because it helps give the game some structure to work from.

& finally because the GSM is, for me, often the least interesting part of the game to develop, it’s easy to overlook, but is very important for giving players a sense/feel about the product as a whole.

 


 

My most recent experience building GSM’s comes from developing Xbox 360 indie titles. In that environment I used ‘screen-managers’.

XNA GSM Sample code

Explanation from XNA;

The ScreenManager class is a reusable component that maintains a stack of one or more GameScreen instances. It coordinates the transitions from one screen to another, and takes care of routing user input to whichever screen is on top of the stack.

Each screen class (including the actual gameplay, which is just another screen) derives from GameScreen. This provides Update, HandleInput, and Draw methods, plus some logic for managing the transition state. GameScreen doesn't actually implement any transition rendering effects, however: it merely provides information such as "you are currently 30% of the way through transitioning off," leaving it up to the derived screen classes to do something sensible with that information in their drawing code. This makes it easy for screens to implement different visual effects on top of the same underlying transition infrastructure.

This is very different to the way the GSM’s are handled in the Unity tutorials – Notably the ‘tanks‘ and ‘space shooter‘ sample code.

I figured I could replicate the XNA screenmanager GSM framework by using separate scenes instead of separate screens – Simple to implement and fairly clean.

But I figure part of the point of learning is to try something new, so I’ve used the  ‘tanks‘ and ‘space shooter‘ set-up for the GSM – If it works, hooray – If not, at I’ll know 🙂

 


 

Initially I pretty much ripped the ‘space shooter‘ GSM code wholesale.

It’s a nice simple set-up, easily replicable & I thought I could plug it in fairly easily…

I created an empty game object – called it ‘GameController‘ added a new C# script (also called ‘GameController’) – Into the script, I pulled over the relevant score, restart and game over code.

I added a UI-Text component, played with it a little, but as a rule I just replicated the settings from the ‘space shooter‘ game – Plugged these text components into ‘GameController‘ script, allowing it to handle when to display what text.

In the game itself, I needed to identify when it was game over – Since I’m just trying to set things up, I decided to keep things simple – If the players cube is at position -11 on either the X or Y coordinate (outside the screen to the left, or bottom)- Then it’s game over.

To make sure ‘GameController‘ reacted to the game over state – I created a global static bool called InGame – If InGame is true, game is running, if InGame is false then display the ‘Game Over text.

I added a little extra code to the player and platforms scripts – Ensuring they only updated when InGame was true.

But otherwise, that was pretty much it – It took a little smoothing, but it worked quite nicely.

 


 

The problem was, it was only a game over screen – At the moment, when the game starts running, it throws the player immediately into the game – Which I felt would be very confusing and a little off-putting for someone who’d just started the game up – I needed a title screen.

Again, I wanted something simple that played nicely with the modified ‘space shooter‘ ‘GameController‘ code.

Following the code in place;

When the game initially starts/loads InGame is set to false this ensures text is displayed and the player isn’t thrown, unexpectedly into the action.

Since the game has only just loaded, it seems a little rude to display the ‘Game Over‘ screen straight away.

I added an extra text field to hold the games title – currently called ‘TEST GAME‘ – Linked this into the ‘GameController‘ code.

I needed to figure out when to display the game title and when to display game over –

This I fudged – Given the interface I’d decided to work with, I wasn’t too sure of the best approach.

Creating a static bool called ‘counter‘ (originally it was an int, after updating I forgot to change the name). If counter == true then the games title text is displayed, if counter == false, then the game over text is displayed. By making the bool static, it keeps it’s value even after ‘SceneManager.LoadScene‘ is called.

 


 

Full ‘GameController‘ code;

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.SceneManagement;
public class GameController : MonoBehaviour
{
     //---
     //---
     public static bool inGame;
     private float scoreActual;
     private int scoreDisplay;
     public Text scoreText;
     private bool restart;
     public Text restartText;
     private bool gameover;
     public Text gameoverText;
     private bool title;
     public Text titleText;
     public static bool counter = true;

     //---
     //---
     // Use this for initialization
     void Start()
     {
          scoreActual = 0;
          scoreDisplay = 0;
          UpdateScore();
          gameover = false;
          gameoverText.text = "";
          restart = false;
          restartText.text = "";
          //---
         if (counter)
          {
               title = true;
               titleText.text = "TEST GAME";
               counter = false;
               inGame = false;
          }
          else
          {
               title = false;
               titleText.text = "";
               inGame = true;
          }

     }
     //---
     //---
     // Update is called once per frame
     void Update()
     {
          if (restart)
          {
              if (Input.GetKeyDown(KeyCode.R))
               {
                    SceneManager.LoadScene(Application.loadedLevel);
               }
           }
              else if (title)
               {
                    if (Input.GetKeyDown(KeyCode.R))
                    {
                         title = false;
                         titleText.enabled = false;
                         inGame = true;
                    }
          }
          else
          {
               AddScore(0.1f);
               UpdateScore();
          }
     }
     //---
     //---
     void UpdateScore()
     {
          scoreText.text = "Score: " + scoreDisplay;
     }
     //---
     //---
     public void AddScore(float newScoreValue)
     {
          scoreActual += 0.1f;
          scoreDisplay = (int)scoreActual;
          UpdateScore();
     }
     //---
     //---
    public void GameOver()
     {
          gameoverText.text = "Game Over";
          gameover = true;
          restartText.text = "Press 'A' to restart";
          restart = true;
          Debug.Log("GAME OVER GAME OVER GAME OVER");
          inGame = false;
     }
     //---
     //---
}

 


 

So I had a basic GSM – A little funky, but it works – It’s an approach I hadn’t tried before & it’s simple enough that I can either adapt it (if I want to stick with the code) – Or remove it if I decide to go for something more substantial.

 


 

Play this build (WebGL)

 


 

Grab a copy of the project here

 


 

 


 

Next post: 1.4a Tighten & Tidy

Last post: 1.2 Initial Code

Contents page.

 


 

Advertisements

2 Replies to “Adventures in Unity – 1.3 Initial GSM”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s