Unity單例模式,但是是取自Ultrakill反編譯程式碼

ComputerEngine發表於2024-07-18

以下是用dnSpy對Ultrakill原始碼反編譯後拿到的MonoSingleton寫法,刪去了一部分應該是需要關聯其他東西的程式碼。

using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.SceneManagement;

public abstract class MonoSingleton<T> : MonoSingleton where T : MonoSingleton<T>
{
	private static T Initialize()
	{
		if (!MonoSingleton<T>.flags.HasFlag(SingletonFlags.NoAutoInstance))
		{
			GameObject gameObject = new GameObject(typeof(T).FullName);
			T result = gameObject.AddComponent<T>();
			if (MonoSingleton<T>.flags.HasFlag(SingletonFlags.HideAutoInstance))
			{
				gameObject.hideFlags = HideFlags.HideAndDontSave;
			}
			if (MonoSingleton<T>.flags.HasFlag(SingletonFlags.PersistAutoInstance))
			{
				Object.DontDestroyOnLoad(gameObject);
			}
			return result;
		}
		if (!SceneManager.GetActiveScene().isLoaded)
		{
			return Object.FindObjectOfType<T>();
		}
		return default(T);
	}

	public static T Instance
	{
		get
		{
			if (!MonoSingleton<T>.instance)
			{
				return MonoSingleton<T>.instance = MonoSingleton<T>.Initialize();
			}
			return MonoSingleton<T>.instance;
		}
		protected set
		{
			MonoSingleton<T>.instance = value;
		}
	}

	protected virtual void Awake()
	{
		if (MonoSingleton<T>.instance && MonoSingleton<T>.flags.HasFlag(SingletonFlags.DestroyDuplicates) && MonoSingleton<T>.instance != this)
		{
			Object.Destroy(this);
			return;
		}
		if (MonoSingleton<T>.flags.HasFlag(SingletonFlags.NoAwakeInstance))
		{
			return;
		}
		if (MonoSingleton<T>.instance && MonoSingleton<T>.instance.isActiveAndEnabled && !base.isActiveAndEnabled)
		{
			return;
		}
		MonoSingleton<T>.Instance = (T)((object)this);
	}

	protected virtual void OnEnable()
	{
		MonoSingleton<T>.Instance = (T)((object)this);
	}

	protected virtual void OnDestroy()
	{
	}

	private static T instance;

	private static readonly SingletonFlags flags;
}

(感覺是Pitr或者其他程式設計師寫的,反正不是Hakita寫的就是了)

相關文章