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;
}
}