This is btw, slightly different than the proposed singleton pattern. But in your case I don’t think you really need one.
If you care about what the differences are, well singletons are better suited to Unity because static information tends to linger for longer, for example when you exit play model, which is usually undesirable. Here we make sure we clear the relevant fields on destroy, HOWEVER, if you don’t, the whole thing might get stuck in an invalid state (which is easily solved by removing the script and adding it again).
The other reasons are mostly from object oriented standpoint, but that kind of reasoning is moot for the most part, unless your project is really big and/or has many moving parts and/or several collaborators.
Let’s fix this issue with the above code so that you can reset the internal state manually. You just add this
void Reset() => _levels = null;
You can now select Reset in the top-right corner in the inspector.
Let’s also add a little something so that we can see what the next level will be.
Create a new folder and call it Editor
in it place a new script called SceneLoaderEditor
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(SceneLoader))]
public class SceneLoaderEditor : UnityEditor.Editor {
public override OnInspectorGUI() {
base.OnInspectorGUI();
var nextLevelName = "<Uninitialized>";
if(SceneLoader._levels is not null) {
var next = SceneLoader._currentLevel + 1;
if(next >= 0 && next < SceneLoader._levels) {
nextLevelName = SceneLoader._levels[next];
} else {
nextLevelName = "<Out of range>";
}
}
var enbl = GUI.enabled;
GUI.enabled = false;
EditorGUILayout.StringField($"Next Level", nextLevelName);
GUI.enabled = enbl;
}
}
Now you should be able to inspect the internal state of this script.
Edit: Don’t try this ^^ yet, I should really run this first, to weed out the errors. I.e. quite possibly you should make the original _levels and _currentLevel variables public, can’t work this out from my head.
Edit2: Made a silly mistake, fields are static anyway, and yes they should be declared public. I’ll make a better version of this in the following posts.
Ah yes, sure. That’s why I did that in Awake.
ok bring back Awake like this
void Awake() => Object.DontDestroyOnLoad(this);
and remove this line from LoadNextLevel