Game Structure


iPhone 3.5 @2x 960x640

A character select screen with automatic setup

The Game Structure features provide the ability to quickly and simply setup a game with common features such as Players, Worlds, Levels and Characters. It offers automatic setup including all the components you need to create menus and otherwise interact with them.  All of these features are integrated into other areas of the framework to include localisation, in app purchase, dialogs and more.

These pages contain more complex reference material for a deeper understanding of how things work. As an introduction to many of these concepts we recommend first going through the Getting Started Tutorial.

This page provides an overview of some of the key elements within the Game Structure section. For more specifics please see:

  • Characters – For working with multiple characters / vehicles etc.
  • Colliders – Automatic handling of collisions
  • GenericGameItems – Generic GameItem implementation for your own purposes.
  • Levels – Setup and working with levels
  • Players – Working with the current player
  • Worlds – Setup and working with worlds

Key Elements

The following diagram shows some of the key game structure concepts and how they relate.

Some of these key items are shown below and also covered in more detail following the diagram. Of these the most important are GameManager that provides global state and management and GameItem form the basis of many other concepts.

Game Manager

GameManager

One of the central components is the GameManager component and you will typically always add this to your scene. GameManager stores a lot of useful information and references such as screen dimensions, events for screen orientation changes and is where you can configure and retrieve details about how your game will work, including the automatic creation of things like players, worlds and levels. Several of these are described further below in this document.

As it is persisted across scene changes, we recommend always creating a gameobject in your scene called _GameScope and adding this and other such persistent components to this gameobject. One practice is to make _GameScope a prefab so it can be added to all scenes allowing you to test them directly. As GameManager is a singleton, if you move to a new scene and it is already created then a new one won’t be added.

Within GameManager you can configure a game structure that will be automatically created including Player defaults, whether you are using worlds and levels, characters and the default values for these.

Game Manager support for Audio, Preferences, Display, Messaging and Localisation is described further in the relevant documentation pages. It is also recommended to read the GameManager API documentation as this is a central component that you will often use.

GameItems

As mentioned above, GameManager holds references to the game’s Players, Levels, Worlds and Characters which all inherit and build upon the GameItem class and who’s configuration can be dynamically loaded and configured through the Unity editor.

Before moving on further, it is a good idea to understand what GameItems are and how they can be used, as they gives some standard functionality that allows you to treat all derived classes in a standard manner. As an example, when you access the current level through GameManager.Level.Selected you will see that the GameItem properties are available as a part of the returned Level, so you will have access to it’s ID, Name etc.

Key Properties

GameItem holds some key properties including:

  • IdentifierBase – I unique identifier for this type of GameItem. e.g. “Level” or “Player”
  • IdentifierBasePrefs – Similar to above, but a shortened form to save memory (used for preferences).
  • ID – A unique number (within it’s type) for this item.
  • Name – A name for this item that can be specified or loaded automatically from localisation.
  • Description – A description for this item that can be specified or loaded automatically from localisation.
  • Prefabs – A list of localisable prefabs that can be used for custom or predefined functionality (e.g. selection menus).
  • Sprites – A list of localisable sprites that can be used for custom or predefined functionality (e.g. selection menus).

Configuring GameItems

You can opt for either automatic or explicit configuration of game items

Automatic configuration

In the abscence of any explicit configuration, GameItems will be given a default configuration . This includes trying to use localised keys in the format [IdentifierBasePrefs][Number].Name (e.g. L1.Name) to retrieve the GameItem name, [IdentifierBasePrefs][Number].Desc (e.g. L1.Desc) to retrieve the GameItem description, and looking for an associated sprite in a resources folder with a path Resources\[IdentifierBase]\[IdentifierBase]_[ID].

While automatic configuration can be of use to get up and running quickly, Game Framework v4 introduces new configuration options that are a lot more powerful and so explicit configuration is now recommended. If you use automatic configuration you will see a warning to this effect along the lines “Unable to find Level GameItem in resources folder Level\Level_1 so using defaults” although you can chose to ignore these messages if you chose so.

Explicit configuration

When a GameItem is initialised, Game Framework will try and load per game item configuration from the path Resources\[IdentifierBase]\[IdentifierBase]_[ID]. These configurations contain things like the name, description, sprites, prefabs in addition to any GameItem specific settings and the configuration files them selves can be created directly within the Unity editor. The picture below shows Level configuration with the standard GameItem configuration items and level specific settings.Note how Name and Description allow for specifying a fixed value or localisation key (the latter are preferred and will be integrated further in later versions).

gameitemconfiguration

New configuration items can be added by right clicking the folder where they should be added and selecting one of the options from teh Create | Game Framework menu.

creategameitem

Prefabs

Each GameItem can hold a list of localisable prefabs for either custom or predefined functionality (e.g. selection menus, unlock windows).

You can access references to these by either name or type using the GameItem GetPrefab…() methods. There is also an InstantiatePrefab component that most of the GameItem implementations provide versions of that will create an instance of the specified prefab. The GameStructure demo uses the InstantiateLevelPrefab implementation to instantiate a different prefab for the player to control based upon the selected level and the prefab of type InGame.

Sprites

Each GameItem can hold a list of localisable sprites for either custom or predefined functionality (e.g. selection menus, unlock windows).

You can access references to these by either name or type using the GameItem GetSprite…() methods. There are also SetImageToSprite and SetSpriteRendererToSprite components, that most of the GameItem implementations provide versions of, that will substitute GameItem instance specific sprites to UI Image controls and SpriteRenderers respectively. The GameStructure demo uses the SetImageToLevelSprite implementation to automatically show a level specific sprite, in game, of type SelectionMenu.

As a fallback to configured sprites you can also place a sprite with a name Resources\[IdentifierBase]\[IdentifierBase]_[ID] that will be used in certain cases if no explicit sprite is configured. As discussed previously however explicit configuration is to be preferred.

Score and Coins

GameItem allows for the tracking of scores, high scores and coins and provide a number of methods and properties for interacting with these. Changes will cause CoinChangedMessage, HighScoreChangedMessage or ScoreChangedMessage messages to be generated accordingly so that your other components can easily react to such changes. Certain derived types such as Level and Player send their own custom message types instead so you can easily determine the source of these events.

There are many possibilities for combining and use of these score and coin features, however one common scenario is to associate the total game score with the current Player and having a separate level score that is either added to the total score either immediately or if they win the level. There are components described in the Player and Level sections that support such scenarios.

Unlock and In App Purchase

GameItems support both unlock and In App Purchase with a couple of key properties:

  • IsBought – Whether a gameitem is purchased.
  • IsUnlocked – Whether a gameitem is unlocked (a purchased item is automatically marked as unlocked).

There are various ways of unlocking specific gameitems such as levels which are covered later.

GameItem Specific Preferences

It is common to need to save and retrieve per GameItem values and this is supported through the GetSettingXXX() and SetSetting() functions. These functions are used for setting standard values such as the GameItem score or unlock status, but can also be used for setting your own values e.g. if you wanted to save the level progress you could call something like level.SetSettingFloat(“Progress”, 0.5f). These values are saved in PlayerPrefs but automatically prepended with the GameItem’s IdentifierBasePrefs and ID so they are unique for each instance of the gameitem as shown in the diagram below.

PrefsWindow

The ‘Prefs Editor’ asset included in the extras bundle showing Player GameItem properties (under Windows | Prefs Editor)

Derived Classes

The framework provides support for state management, scores, unlock status, in app purchase, custom data loading, localisation, display and updating of all GameItem based classes. Entities that inherit from GameItem often add their own specific features, such as Level adds ‘stars won’ support. We encourage you to view the API documentation to understand these concepts further if they sound relevant.

You can easily also easily define your own custom subclasses if you have a need that isn’t met by the existing ones or wish to add additional functionality to an existing type. For example the below adds an additional LocationName configuration field to Levels that you can access and reference within your own code:

With the above added to your project just use the new Custom Level menu item to create levels and they will be loaded automatically. To access these custom values just cast references to your new type :

Note: Be sure that your class and the file it is contained within have the same name (e.g. CustomLevel.cs) to avoid issues with missing script references.

It can seem daunting, but it is a simple, powerful and expandable system that is quickly learnt. We recommend going through the Getting Started tutorials and trying out the FullGameBasic and 2DInfinateRunner samples included in the extras bundle. These will help you to understand more clearly what is supported out of the box and how you can extend the framework for your own needs with a minimum of work.

Extended Configuration

When creating your game you will often need to store custom per-GameItem configuration and functionality, The easiest way to do this is as discussed above in derived classes. In certain cases you might only want to load this information on demand rather than having it loaded at all times, for instance when there is quite a lot of data. This is supported through two methods.

GameItemExtension

The GameItemExtension base class works in a similar fashion to standard Game Item configuration files in that it can be created and managed through the Unity editor. As it is for custom configuration however GameItemExtension doesn’t define any properties as it is expected that is something you will do by creating a GameItemExtension derived class (in a similar fashion as discussed above). GameItemExtensions should be created in a subfolder within the resources folder along with the standard GameItem configuration files where the name is in the format [IdentifierBase]\[IdentifierBase]_[ID]_Extension.

GameItemExtensions will be loaded automatically if the ‘Load From Resources’ option is enabled either in GameManager or can be manually loaded through code using the GameItem.LoadData() method. Any loaded GameItemExtension is available through the GameItem.GameItemExtensionData property or via the GetExtension<T>() method that can be used for casting into the correct implementation type.

The Getting Started tutorials provides a walk through on doing this.

JSON Configuration

You can also place json files in a subfolder within the resources folder that will be loaded automatically if the ‘Load From Resources’ option is enabled either in GameManager or through code using the GameItem LoadData() or LoadJsonData() methods. The name of such a file is in the format [IdentifierBase]\[IdentifierBase]_[ID].json.

JsonResources

The entire json is available through the GameItem JsonConfigurationData property so you can easily access custom properties.

In general GameItem configuration files are preferred due to the more structured and more easily extensible approach.

GameItem Support Components

There are a few of other base classes and components that work with GameItem to simplify and ease usage of the standard and your own custom implementations

GameItemManager

GameItemManager is a generic class used for managing an collection of related GameItems of a specified type. Features include setup, selection, unlocking and more. A GameItemsManager of type Level might for example hold all the levels in your game, indeed this is what GameManager does for holding the current Worlds, Levels, Characters, Players and more.

You can access all the GameItem instances that a GameItemsManager contains through the Items property. Specific items can be retrieved through the GetItem() and GetNextItem() methods and the currently selected item through it’s Selected property.

GameItemsManager provides the Load() method to create GameItems and set them up as described above. The below code shows a slightly edited version from GameManager of how it automatically sets up levels. You can of course create and store references to your own GameIte,Manager instances.

Once items are loaded, GameItemsManager will ensure that the currently selected GameItem (either the first item or as saved previously) is unlocked and will also mark as unlocked any game item with a ValueToUnlock of 0.

GameManager holds references to instances of GameItemsManger for Worlds, Levels, Players and Characters (through the Worlds, Levels, Players and Characters properties). So for example GameManger.Instance.Levels.Selected will return the currently selected Level (which itself inherits from GameItem), or your own Level sibclass if you have created these as described above.

GameItemButton and CreateGameItemButtons

Simple Level Selection

Level GameItem buttons with automatic layout

The GameItemButton abstract class will set up and handle a button representing a GameItem and includes support for things such as displaying values, unlocking and IAP. Specific implementations of GameItemButton such as LevelButton and more extend this functionality.

GameItemButton uses the passed Number to determine the GameItem to display and will automatically hook up the click event of any Button component on the same gameobject. The behavior when the button is clicked can be adjusted by setting the SelectionMode to:

  1. ClickThrough – The button will behave like a standard button. Usually combined with specifying aClickUnlockedSceneToLoad value.
  2. Select – Behave like a radio button with only one button at a time selected showing the highlight image (see below). Typically used when you want to show further information about the selected GameItem such as detailed stats or a rotating 3D model, rather than going directly to the next scene (you would then need a separate button to change scenes).

In either case if the button is unlocked then the associated GameItem will be marked as the selected one if specified, ClickUnlockedSceneToLoad  will cause the specified scene to be loaded. For the scene name you can either have a fixed scene, or add in the formatting parameter {0} to have the GameItems number substituted when determining the scene (e.g. “Game{0}” might become Game1, Game2, …). The choice will depend on how you are structuring your game and whether you are doing static or dynamic scene layout.

The clicked behavior is also dependent on how you are unlocking the item and support for IAP. If a button is locked and IAP is enabled then clicking the button will automatically invoke the purchasing process with subsequent unlocking of the level. If the corresponding GameItem’s ValueToUnlock is anything other than -1 then the button will also be available for unlocking by collecting coins (more information further down).

The layout and display of the button can be easily customised. Child gameobjects with the below names and components take on special meaning as mentioned below:

  • “Name” (Text Component) – replaced with the GameItems name
  • “HighlightImage” (Image Component) – Enabled only on the selected item if using SelectionMode “Select”.
  • “Sprite” (Image Component) – Replaced with a GameItem Sprite of type SelectionMenu or the default one loaded from resources.
  • “Lock” – Enabled for all locked buttons.
  • “ValueToUnlock” – Enabled if the button is locked and the GameItem’s ValueToUnlock is not set to -1, otherwise disabled
    • “ValueToUnlockAmount” (Text Component) – Shows the amount needed to unlock this item. The text is colored in the color specified by CoinColorCanUnlock if the user has enough coins to unlock this GameItem, otherwise the color specified by CoinColorCantUnlock
  • “HighScore” – Enabled if the button is unlocked otherwise disabled
    • “HighScoreText” (Text Component) – Shows the GameItems’s high score.

Finally when the GameItem that this button represents is unlocked through IAP, Coins or otherwise the button will set the Unlock trigger on any attached Animator so you can animation the unlocking.

Specific implementations of GameItemButton may also add additional features to the above or modify the behavior. For the built in types these differences are listed in the pages for player, world etc.

Adding GameItemButtons to Your Scene

You can either add derived instances of GameItemButton directly to your scene to create a non-linear selection screen, or use a derived instance of CreateGameItemButtons such as CreateLevelButtons to automatically create instances of a prefab for all relevant GameItems (including setting the Number’s into GameItemButton scripts on the prefab.

UnlockGameItemButton

The UnlockGameItemButton abstract class and it’s specific implementations such as UnlockLevelButton allow for unlocking new items based upon the players number of collected coins and the Coins to Unlock value of the individual gameitems. If you want this kind of functionality then add a UI button into your scene and attach the relevant component. The rest is take care of automatically.

unlocklevelbutton

By default the unlock dialog that appears when a user clicks the button will have the name and sprite (of type Unlock Window) associated with the GameItem. By optionally specifying a content prefab and animator you can customise and animate the dialog as is done below (one of the demos from the extras bundle) that shows a spinning cube before showing what was unlocked.

UnlockLevel

You can customise the text in all of the displayed dialogs (see the localisation section for details).

Game Namespace

The Game Namespace contains a number of general classes and components relating to game setup and structure.

Game Unlocking

Many games follow the freemium model where the game is offered for free and you can somehow unlock the full game, either through an in app purchase or performing some action. Game Framework supports these scenarios and the current unlock status is recorded in the GameManager IsUnlocked property. You can update this value through code, or have it automatically updated through in app purchase.

You can directly check the IsUnlocked property to get the current unlock status, alternatively changes to the unlock status will cause a GameUnlockedMessage message to be sent out that you can listen for and handle accordingly. The EnableBasedUponGameUnlocked component can also be used and will show one of two gameobjects based upon whether the game is unlocked. The component listens for GameUnlockedMessage messages to automatically update the display on changes.

GameHelper

The GameHelper class contains helper functions about the overall game structure and status. With this class you can do things like check if the current level is the last in the game (IsCurrentLevelLastInGame())without worrying about the details of the internal setup. The classes mentioned above and their specific implementations also provide helper functionality although typically only relating the the GameItem type which they implement.

Device Orientation and Resolution Changes

Certain devices allow for changes in the orientation and resolution. Gamemanager will monitor for these and send out the DeviceOrientationChangedMessage and ResolutionChangedMessage messages when such changes occur. You can listen for these and react accordingly such as updating the display.

See also

If you have any thoughts or suggestions on improvements or additions to the Game Structure features then please let us know!