Part 3: Creating the Game State Management Script

This post follows: Part 2: Writing Scripts for Unity

The sample Mars Base project design calls for managing four different resource types – air, water, food and power. The values of these resources change over time so we’ll be controlling the values through an Update() method. We’ll create a script that is derived from MonoBehavior to use the update function. The script needs to be attached to a GameObject in the scene to function, we typically setup an empty GameObject to hold the scripts.

In a larger, more complex project involving multiple scenes this type of management object should be implemented as a singleton since we’ll be using the same resource values across the app, I’ll cover that later when we create multiple scenes for the project . For now, we only have 1 scene so I’ll keep the script simple.

To hold the resource values, we’ll use floats and each will represent the remaining units in the Mars Base and define the production and consumption rate.

using UnityEngine;
using UnityEngine.UI;

public class StateManager : MonoBehaviour
{
    // UI Elements
    public Text AirText;
    public Text WaterText;
    public Text FoodText;
    public Text PowerText;
    public Text AlertText;

    // Tracking Variables
    public float AirLevel;
    public float WaterLevel;
    public float FoodLevel;
    public float PowerLevel;

    public float AirMaxLevel;
    public float WaterMaxLevel;
    public float FoodMaxLevel;
    public float PowerMaxLevel;
    
    // System State Tracking
    private bool shutdown;

    // Properties Accessible via Unity Events
    public float AirGeneration { get; set; }
    public float WaterGeneration { get; set; }
    public float FoodGeneration { get; set; }
    public float PowerGeneration { get; set; }
    public float AirConsumption { get; set; }
    public float WaterConsumption { get; set; }
    public float FoodConsumption { get; set; }
    public float PowerConsumption { get; set; }


    void Start()
    {
        shutdown = false;
        AlertText.gameObject.SetActive(false);  // Disable Shutdown Notice
    }

    void UpdateDisplay()
    {
        AirText.text = string.Format("Air: {0}", AirLevel.ToString("N0"));
        WaterText.text = string.Format("Water: {0}", WaterLevel.ToString("N0"));
        FoodText.text = string.Format("Food: {0}", FoodLevel.ToString("N0"));
        PowerText.text = string.Format("Power: {0}", PowerLevel.ToString("N0"));
    }

    void UpdateValues()
    {
        AirLevel += (AirGeneration - AirConsumption) * Time.deltaTime;
        AirLevel = Mathf.Clamp(AirLevel, 0f, AirMaxLevel);
    }

    void ShutdownAction()
    {
        shutdown = true;
        AlertText.gameObject.SetActive(true);   // Activate Shutdown Notice
    }

    void Update()
    {
        if (shutdown)
            return;

        UpdateValues();
        UpdateDisplay();

        // Shutdown Conditions
        if (AirLevel <= 0f || WaterLevel <= 0f || FoodLevel <= 0f)
        {
            ShutdownAction();
        }
    }
}
  • The sample is setup to use a text UI display to indicate the current Level (value) of the resource.  We can change this later to a bar graph or a nicer indicator.
  • Properties are used for the Generation and Consumption rates so they can be accessed by Unity events we’ll be getting from the Slider UI.
  • To quickly see results, we’re configured to use a “per-second” rate of change by multiplying our value by Time.deltaTime; we can switch to a per-minute rate by dividing the value further by 60

To test and demonstrate the setup, I’ll create a new scene with Text and Slider UI to show the change in values in the next post.

For questions, comments or contact – follow me on Twitter @rlozada

Next: Part 4: Using the State Management Script