I’m working on some solutions and I’m attempting to have a GameManager class for all of my games. This should:
- Persist across levels/scenes.
- Be serializable and visible in the Unity Editor.
- Be scene-agnostic - meaning, I can start the game at any scene for debugging purposes.
I’ve been able to accomplish #1 with DontDestroyOnLoad
. However, I’m having conflicts between #2 and #3.
If I want #2 - “the object should be serializable and visible in the Unity Editor” - I have to derive from MonoBehavior, or ScriptableObject. The issue with Monobehavior is that it requires a gameObject, meaning that there must be an instance in a scene somewhere. ScriptableObjects, unfortunately, are similar; while they don’t have to be attached to a gameobject, they must be referenced from an active object (as a property) in order to be used.
If I want #3 - starting the game from any scene - I can make the class a singleton, or a static class; this means I can instantiate the object in code without having to have a gameObject in the scene, but then I run into configuration issues. Creating the class from code means that Unity has no way to serialize data in the editor (unless I’m missing something fundamental).
I attempted to use AssetDatabase.LoadAssetAtPath
, thinking that I could generate my Singleton by loading my GameManager scriptableObject from disk, but AssetDatabase
is in the UnityEditor namespace. It won’t work in a build.
public class _GameManager : ScriptableObject {
private static _GameManager _instance;
public static _GameManager getInstance() {
if (_instance == null) {
Debug.Log ("GAMEMANAGER INSTANCE NULL");
// _instance = ScriptableObject.CreateInstance<_GameManager>();
_instance = AssetDatabase.LoadAssetAtPath("path/to/gamemanager");
}
return _instance;
}
What’s best practice for this? Do I need to create a GameManager prefab and instantiate that when the game runs? That would allow me to satisfy #2, and maybe #3, but it seems…incorrect, somehow, since a prefab is supposed to be a template.