CS2335
Master 1.0.0
Master 1.0.0
  • Introduction
  • Introduction
    • Introduction
      • Game Design
    • Unity - Download
    • Visual Studio - IDE
    • Unity Manual, Scripting API
  • Unity Basics
    • Unity Editor Windows
    • Behavior Components
    • 2D Project, Scenes
      • Create 2D Sprite GameObject
      • Create UI-Text GameObject
    • MonoBehavior - Base-Class
    • Create a Custom C# Script
  • Game Coding Structures
    • Games Overview
    • Unity Engine - Event Functions
    • Finite State Machines
    • UML Class Diagram
  • Animation
    • Animator Controller
    • Animation Steps
      • Optional: Dead Animation
    • PlayerController.cs V0
  • Project 1 - Player
    • Player GameObject v1
      • C# Generics, Statics
    • Player GameObject - Jump
    • PlayerController.cs V2-Jump
    • PickUp PreFabs
      • Sorting Layers
    • PlayerController.cs V3-Collide
    • GameData Version1
    • GameData Version2
    • PlayerController V4-Score
  • Project 1 Details
    • Project1 GameObjects
    • PlayerStats Version1
      • UI-Canvas
    • Utility Class
    • Simple Spawner
    • MiniGameManager
      • Logic Diagrams
      • StartButton
      • ResultsPanel
  • Project1 Enhancements
    • PickUp - SelfDestruct
    • Spawn from List of Prefabs
  • Project 2 - StateManager
    • Project 2 - Learning Objectives
      • Inspiration
        • Branching Story Structures
        • Branching Structures
        • Hero's Journey
        • Visual Novel in Unity-Links
    • Project 2 - Starter Assets
    • State Machine Framework
    • StateManager - Singleton Design Pattern
    • Interface IStateBase
    • Create SceneXState.cs
    • OptionPanel Prefab
      • UI Images: Sprite Sheets
      • Button Image-Transitions
    • Project 2 - List of Steps
    • Project 2 - Starter Code
  • Project 2 -Dialogue
    • Hide_Show_Panel Script
    • Edit OptionPanel
    • Simple DialogPrefab
    • Conversation Entry
    • SimpleDialog.cs
    • ScriptableObjects
      • Scriptable Object Factory
    • Conversation Scriptable Objects
    • DialogManager_ConvList
      • DialogManager V2
      • Coroutines: Dynamic Text
      • DialogPrefab wImage
  • Overview: Branching Logic
    • DialogTrigger
    • Dictionary Data-Structure
      • Unity PlayerPrefs Dictionary
    • GameData Version3
    • Dictionary: choiceData
      • SaveChoice, ChoicePanel
        • choiceData - examples
          • Dictionary Value to Disable Options
    • Configure UI-Button Listeners
      • NPC Animation
      • NPC Activation
    • UI-Triggered Animations
    • Simple Inventory
    • EndState Conditions
    • Script ExecutionOrder
    • Custom UnityEvents
    • PlayerStats v2
      • ModifyPlayerData
      • BuyItem
    • Text Input
  • UI Components
    • Finding Game Objects
    • Game Objects: UI vs. 2D Sprite
    • UI Elements
      • Canvas: Screen-Space Render-Mode
      • UI-Buttons To Change Scene
  • Proj4: Inventory System
    • Inventory-System
      • GameData version4
      • Install and Configure
      • Diagrams, Resources
        • Item, Gem, Potion Classes
        • Inventory Class
      • InventoryDisplay, Slot UI
        • InventoryDisplay Class
        • Slot Class
        • Hazard Class
        • Layout Groups
      • Customization Steps
        • Configure Animation
        • AddItem Button
        • Concrete Class: Food
        • MiniGame Mods
          • PlayerController Mods
      • Code: InventorySystem
        • GameData, PickUp Mods
      • Resources: Data Structures
  • Custom Unity Events
    • Event Publishing Patterns
    • Custom Event Messaging
  • Proj4: Mini-Game
    • Simplified Mini-Game
      • PlayerController_v2 Mods
        • PlayerController_v2_final
      • MiniGameManager_v2
    • MiniGame-Overview-Proj4
    • LevelManager
      • LevelManager Logic Diagram
      • LevelManager FSM
      • LoadLevel, StartLevel Logic
      • Code Framework
    • Timer
  • Project 4 - Code Mods
    • Project 4 - Steps
    • Project 4 - Code
      • Code: Final Versions
        • PlayerController Mods
          • PlayerController_v2 Mods
        • GameData - Final
        • LevelManager
        • PlayerStats - Final
        • PickUp, Hazard, ScorePickUp
        • Spawner - Final
        • CameraFollow
        • ScreenFader
        • MiniGameState
        • Example: EndState
      • MiniGameWin Logic
  • Optional, Supplemental Content
    • Optional Content
      • Particle Systems
      • Adding Audio
      • Screen Fading and Reloading
      • ScriptableObjects
      • Disable Debug Logging
      • Events and Actions
      • Saving Data - Serialization
      • Parallax Scrolling
      • Change Sprites
    • XR - Extended Reality
  • Computing Concepts
    • Programming Patterns
      • State - FSM
      • Singleton Pattern
    • C# Language
      • Variables
      • Delegates
      • Dictionary
      • Enum
      • Encapsulation
        • C# Properties
        • Access Modifiers
      • Generics < T >
      • Inheritance
      • Interface
      • List< T >
      • Polymorphism
      • Queue< T >
      • Switch-Case
      • Foreach
      • Static
      • Ternary Operator: ?
      • this
    • Diagrams
      • State Machine Framework
      • UML Class Diagrams
      • Level Manager Logic Diagram
      • Flow-Chart: NumberGame
      • FSM: NumberGame
    • Tools
    • Glossary
    • References and Resources
    • Random Thoughts
Powered by GitBook
On this page
  • StateManager - Singleton Design Pattern
  • Learning Goals:
  • Object Persistence
  • StateManager ObjectReferences
  • StateManager - SwitchState( )
  • StateManager Code

Was this helpful?

  1. Project 2 - StateManager

StateManager - Singleton Design Pattern

PreviousState Machine FrameworkNextInterface IStateBase

Last updated 4 years ago

Was this helpful?

StateManager - Singleton Design Pattern

Learning Goals:

  • Learn how to use Singleton Programming Pattern to create persistent GameObjects and Script Objects.

  • Learn how to define and use Interfaces like: IStateBase to create object references like: StateManager: activeState for objects that from classes that implement the interface.

  • Learn how to define object references and to pass object references as class Constructor parameters to allow class objects to interact via public methods and public properties.

  • Learn how to instantiate objects by calling the class constructor method.

Object Persistence

Unity proivdes a special method that we can use to insure the GameManager and attached script component: StateManager are not destroyed when execution jumps to a new scene: DontDestroyOnLoad(gameObject). Since this StateManager will not be destroyed, then any objects that have an active object reference within the StateManager object will also not be destroyed. We can use this to keep a reference to an Inventory object, so then the inventory will also have persistence throughout the life of the application, We may also want to keep track of which states / scenes that we've visited, by maintaining a list of the object references for states which have been instantiated. We'd need to prevent creation of a new state instance each time we return to a scene.

StateManager ObjectReferences

When each state object is initialized, it's constructor has an input parameter that is an object reference to the singleton instance of the StateManager object, this gets assigned to a local reference variable: manager. Later, we pass that address along to the next state object when it is time to change states by calling the constructor for the next state. The SwitchState process is interesting because the ``SwitchState() method belongs to the StateManager object, but the code is executed from within the current state, but the function requires the current state to call the function by calling the constructor method for the next state. This code really illustrates the fact that methods are used by objects to communicate, they act to allow messages to be sent between objects.

Class Design and some code for the StateManager , IStateBase, and StateX classes is based on projects in the book: Learning C# by Developing Games with Unity 3D Beginner's Guide, Terry Norton. PacktPub eBook Version

StateManager - SwitchState( )

The SwitchState process is quite interesting because the SwitchState() method belongs to the StateManager object, but the code is executed from within the current state, but the function requires the current state to call the function by calling the constructor method for the next state. This code really illustrates the fact that methods are used by objects to communicate, they act to allow messages to be sent between objects.

The UnityEngine provides methods that allow easy message communication between objects, some of these methods are FindGameObject(), AttachListener(), OnTriggerEnter2D(), etc.

Code in BeginState to switch state and scene to correspond to the EndState, EndScene. To do that, first we are assuming that the LoadEndScene( ) method will be activated when the endButton is clicked. Once that happens, we use the Unity SceneManagement's SceneManager static method: LoadScene( "EndScene" ) , here we pass in the name of the Unity Scene that we want to go to. Next, we use the singleton instance for the StateManager so we can call StateManager method: SwitchState(). When calling SwitchState, we first call the constructor for the new state: new EndState( ), and this object is passed as an input parameter for SwitchState( ), this is how StateManager is able to update the value of activeState, so it will now point to the newly created state. These 2 actions must be performed each time we want to leave 1 scene and go to another scene.

public void LoadEndScene ()
{
Debug.Log ("Add Debug Info");
SceneManager.LoadScene ("EndScene"); //actual scene name
StateManager.instanceRef.SwitchState (new EndState ()); //create new state, pass to StateManager
}

StateManager Code

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.SceneManagement;

///
/// CS2335 - Spring 2020
///  
/// <summary>
/// Game Scene. Matches Unity Scenes in Build Settings
/// YOU WILL ADD CODE FOR YOUR SCENES HERE
/// Scene Enums must match your Unity Scene Name
/// </summary>
public enum GameScene
{
    BeginScene = 0,
    EndScene = 1
}

/// <summary>
/// State manager.  Add comments
/// </summary>
public class StateManager : MonoBehaviour
{
    public static StateManager instanceRef;
    public IStateBase activeState;
    public GameScene curScene;

    /// <summary>
    /// Create this singleton instance.
    /// Implement the Singleton Design Pattern - initialize managerInstance
    /// </summary>
    void Awake()
    {
        if (instanceRef == null)
        {
            instanceRef = this;
            DontDestroyOnLoad(gameObject);  //the gameObject this is attached to 
        }
        else
        {   //
            DestroyImmediate(gameObject);
            Debug.Log("Destroy GameObject");
        }

    }
    // Use this for initialization
    void Start()
    {
        activeState = new BeginState(); //must customize for your game
        curScene = activeState.Scene;
        activeState.InitializeObjectRefs();  //call to Initialize BeginState object references

        //next scene change - this event will call OnLevelFinishedLoading custom function
        SceneManager.sceneLoaded += OnLevelFinishedLoading;  //add function to sceneLoaded delegate
    }


    /// <summary>
    /// Switchs the state.
    /// </summary>
    /// <param name="newState">New state.</param>
    public void SwitchState(IStateBase newState)
    {
        activeState = newState;
        curScene = newState.Scene; //set scene based on newState's GameScene enum
        SceneManager.LoadScene(curScene.ToString()); //Use scene name
        //SceneManager.LoadScene( (int) curScene); //use Scene ID
        Debug.Log("Switch Scene/State to: " + curScene );
    }

    //Public method to switch state using nextScene enum
    public void SwitchState( GameScene nextScene )
    {
        switch (nextScene)
        {
            case GameScene.BeginScene:
                SwitchState(new BeginState());
                break;

            case GameScene.EndScene:
                SwitchState(new EndState());
                break;

            default:
                Debug.Log("No match on SwitchState - scene " + nextScene);
                    break;
        } //end switch-block
    } //end SwitchState


    //StateManager needs to know when a new scene has been loaded
    //then it can call: InitializeObjectRefs for the current state
    void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
    {
        int sceneID = scene.buildIndex;
        if (sceneID == (int)curScene)
        {
            Debug.Log("New function in StateManager to initialize new scene objects - exectued");
            activeState.InitializeObjectRefs();
        }
        else
        {
            Debug.Log("Big Problems - Scene & State Mismatch");
            Debug.Log("LevelFinished Loading :Scene Loaded: " + sceneID + " ActiveState Scene Enum: " + activeState.Scene);
        }
    }

} //end class StateManager
Unity GameObject.Find Documentation