Here’s notes from several videos, indicating stuff I want to do or try. Rather than link to each video, let alone an embed, let me shout out EngiGames and Jason Weiman.
- I want to stick my interface in a separate scene. This is contraindicated by EngiGames for small games, but for my RPG, I think it makes sense to have it be its own thing that sits over the top of everything else going on.
using UnityEngine.SceneManagement;
if (SceneManager.GetSceneByName("UI").IsLoaded == false) SceneManager.LoadSceneAsync("UI", LoadSceneMode.Additive);
- Consider, instead, having the menu call
Don'tDestroyOnLoad()
and then swapping immediately to a gameplay scene, rather than monkeying around with additive scenes, though. - If I don’t want to hook up events to buttons using the Unity Button delegates, I can create scripts that handle the button directly. E.g.
// In Start(), using UnityEngine.UI...
button = GetComponent<Button>();
button.onClick.AddListener(YourClickFunctionHere);
- Obviously, I’ll want to be able to grab an instance of some access point to my menu from any other scene. I should be aware that just putting a reference in a public static field in
Awake()
is considered a Very Bad Plan. This is because it is a sloppy singleton that doesn’t do the first part of a singleton’s job — ensure that one, and only one instance of the class exists. This video details a singleton generic that will allow you to turn a Monobehavior into a proper singleton merely by inheriting from it.
Here’s a singleton implementation that is more or less identical to the EngiGames one linked above. Only the names have been changed to protect the record. (By that I mean I read it, I grokked, it, I typed it in myself to ensure I understood what I was doing and why). I use a property instead of a getter method because for some reason I hate methods, even when I’m replacing them with what are secretly just methods.
using UnityEngine; public abstract class singleton<T> : MonoBehaviour where T: MonoBehaviour { static T instance; static bool quitting = false; public static T Instance { get { if (quitting) return null; if (instance == null) { GameObject go = new GameObject(); go.name = typeof(T).Name; instance = go.AddComponent<T>(); } return instance; } } protected virtual void Awake() { if (instance == null) { instance = this as T; DontDestroyOnLoad(gameObject); } else if (instance != this as T) { Destroy(gameObject); } else DontDestroyOnLoad(gameObject); } private void OnApplicationQuit() { quitting = true; } }