public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>

    {

        static T Saved_Instance = null;

        static protected bool IsQuitting = false;

        static object Sync_Obj = new object();


        public static T Instance

        {

            get

            {

                if (IsQuitting)

                {

                    return null;

                }


                lock (Sync_Obj)

                {

                    if (Saved_Instance == null)

                    {

                        T[] objs = FindObjectsOfType<T>();


                        if (objs.Length > 0)

                        {

                            Saved_Instance = objs[0];

                        }


                        if (objs.Length > 1)

                        {

                            Debug.LogError($"There is more than one {typeof(T).Name} in the scene.");

                            return null;

                        }


                        if (Saved_Instance == null)

                        {

                            GameObject go = new GameObject(typeof(T).ToString(), typeof(T));

                            Saved_Instance = go.GetComponent<T>();

                            Saved_Instance._Initialize();

                            Application.quitting += Saved_Instance.OnAppQuit;

                        }

                    }

                }

                return Saved_Instance;

            }

        }


        protected abstract bool Is_DontDestroyOnLoad { get; }

        protected abstract void Initialize();


        void OnAppQuit()

        {

            Saved_Instance = null;

            IsQuitting = true;

        }


        void _Initialize()

        {

            if (Is_DontDestroyOnLoad)

            {

                DontDestroyOnLoad(this.gameObject);

            }


            Initialize();

        }

    }

사용은 public class 클래스이름 : MonoSingleton<클래스이름> { } 하고 선언하고 구현부 메소드들 오버라이딩해서 쓰면 됨
역시나 AddComponent나 new GameObject("오브젝트이름", typeof(클래스이름)) 따위로 인스턴스를 생성하는건 막지를 못해서
차라리 게임 시작시부터 명시적으로 인스턴스를 만드는 방법에 대해 고민중