- Home /
Keep Singleton while creating holder GameObject at runtime?
I used the persistence tutorial to create SIngleton of my game state object and it all works well. I also found that I need to create manually GameObject on scene, so that I have where to attach the game state script. Then I got to idea, what if I create the holder object at runtime using "new GameObject()" and than "AddComponent()" function. Is my Singleton pattern still kept across scenes or I am recreating this game state object every time I enter a new scene?
Game state code:
using UnityEngine;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class SaveLoadGameData : MonoBehaviour
{
public static SaveLoadGameData gameState;
public float experience = 0;
public float score = 0;
void Awake ()
{
if (gameState == null)
{
DontDestroyOnLoad(gameObject);
gameState = this;
}
else if (gameState != this)
{
Destroy(gameObject);
}
}
public void Save ()
{
// saving code
}
public void Load ()
{
// loading code
}
public void ResetGameState ()
{
// reset data to defaults and save.
}
}
[Serializable]
class GameData
{
public float experience = 0;
public float score = 0;
}
MyGameScene.cs file. All other scene scripts inherit from this class as it holds general stuff about each scene.
// default class that includes all necessary stuff about each scene in general.
// All other scene scripts inherit from this class.
using UnityEngine;
using UnityEngine.UI;
public class MyGameScene : MonoBehaviour
{
public Button PlayBtn;
public Button HelpBtn;
protected GameObject gameStateObject;
protected SaveLoadGameData gameState;
protected void Init ()
{
gameStateObject = new GameObject();
gameStateObject.name = Helper.SAVE_LOAD_GAME_DATA_GAME_OBJECT;
SaveLoadGameData.gameState = gameStateObject.AddComponent<SaveLoadGameData>();
SaveLoadGameData.gameState.Load();
gameState = SaveLoadGameData.gameState;
}
// other useful functions for the scene
}
A scene inheriting from MyGameScene:
using UnityEngine;
using UnityEngine.UI;
public class MainMenu : MyGameScene
{
public Text gameTitle;
public Text gameSubtitle;
public Button newGameBtn;
void Awake ()
{
Init();
}
// main menu functions etc...
}
Answer by callen · Dec 22, 2015 at 05:40 PM
There's nothing generally wrong with this pattern, and in fact I use a variant of it myself fairly often.
Something else that I like to do, but I don't know if you'll find this valuable, is to use an accessor to dynamically create my singleton like this:
//MySingletonScript could be any singleton, in this case the SaveLoadGameData script
public static MySingletonScript Instance
{
//Now, MySingletonScript.Instance will never return null!
get {
if(inst == null) inst = createInstance();
return inst;
}
}
private static MySingletonScript inst;
private static MySingletonScript createInstance() {
GameObject gob = new GameObject("MySingletonScript instance");
return gob.AddComponent<MySingletonScript>();
}
Now, since you're abstracting away this process, your Init() method would just need to call SaveLoadGameData.Instance.Load();