Unity3D: Aggregator Manajer Script Otomatis

pengantar


Artikel ini akan fokus pada satu jenis organisasi interaksi antara manajer skrip (disebut singletones), dan khususnya, penggunaan kelas agregator terpisah, yang berisi tautan ke semua manajer instance. Gagasan untuk membuat kelas aggregator muncul di benak saya setelah membaca artikel ini .

Tugas


Saya sampai pada kesimpulan bahwa untuk memalu manajer ke kelas agregator dengan pena mereka sendiri setiap kali sangat merepotkan. Saat membuat manajer baru, Anda harus membuka kelas agregator dan membuat perubahan. Dengan pengalaman yang cukup, Anda dapat mengotomatisasi proses yang membosankan tersebut. Dengan demikian, tugas ditetapkan: pembuatan otomatis singletones dan pengumpul otomatisnya.

Kelas-Singleton


using UnityEngine;
public class Singleton<T>: MonoBehaviour where T: MonoBehaviour
{
	public static T instance { get; private set; }

	public void Awake()
	{
		if (instance == null)
		{
			instance = GetComponent<T>();
			ManagersAregator.addManager(instance);
		}
		else
		{
			Debug.Log($"<color=red>   {typeof(T).ToString()}</color>");
			Destroy(gameObject);
		}
	}

	public void OnDestroy()
	{
		ManagersAregator.removeManager<T>();
	}
}

Implementasi singleton klasik di Unity menggunakan instance static variabel . Metode Sedar () memeriksa untuk melihat apakah instance didefinisikan . Jika tidak, kami mendapatkan referensi ke instance kelas menggunakan kata kunci ini . Tapi sejak itu dalam implementasi tertentu, "templat" variabel kelas T digunakan, ini tidak bisa digunakan. Tapi kita bisa dengan mudah mendapatkan komponen T dari objek tempat skrip digantung. Jika instance didefinisikan, maka itu harus dihancurkan. Dengan demikian, objek akan selalu di atas panggung dalam satu salinan.

Dalam metode Sedar ()elemen baru ditambahkan ke kelas agregator, dan dalam metode OnDestroy () , elemen tersebut dihapus dari kelas agregator.

Membuat singleton dari kelas MyClass adalah sebagai berikut:

public class MyClass: Singleton<MyClass>

Jika Anda perlu menggunakan metode Sedarlah () di kelas MyClass , maka Anda perlu menggunakan kata kunci dasar ( lebih lanjut tentang basis dan warisan ):

new void Awake()
	{
		base.Awake(); //  Awake() -
		// 
	}

Agregator kelas


using System.Collections.Generic;
using UnityEngine;

public static class ManagersAregator
{
	static Dictionary<string, MonoBehaviour> Managers = new Dictionary<string, MonoBehaviour>();

	public static void addManager<T>(T newManager)
	{
		string keyWord = typeof(T).ToString();

		if(Managers.ContainsKey(keyWord))
		{
			Debug.Log($"[ManagersAregator]  -{newManager}-   -{keyWord}-  ");
		}
		else
		{
			Managers.Add(keyWord, newManager as MonoBehaviour);
			Debug.Log($"<color=green>[ManagersAregator]    -{newManager}-   -{keyWord}-</color>");
		}
	}

	public static T getManager<T>(string callback) where T: Singleton<T>
	{
		string keyWord = typeof(T).ToString();

		if(Managers.ContainsKey(keyWord))
		{
			Debug.Log($"<color=yellow>[{callback}]   -{keyWord}-</color>");

			MonoBehaviour mbTemp = null;
			T manager = null;

			if(Managers.TryGetValue(keyWord, out mbTemp))
			{
				manager = (T)mbTemp;
				Debug.Log($"<color=green>[{callback}]  -{manager}- </color>");
			}
			else
			{
				Debug.Log($"<color=red>[{callback}]    -{keyWord}-</color>");
			}

			return manager;
		}

		Debug.Log($"<color=red>[ManagersAregator]    -{keyWord}-   .</color>");
		return null;
	}

	public static void removeManager<T>()
	{
		string keyWord = typeof(T).ToString();

		if(Managers.ContainsKey(keyWord))
		{
			Managers.Remove(keyWord);
			Debug.Log($"[ManagersAregator]    -{keyWord}-   ");
		}
		else
		{
			Debug.Log($"[ManagersAregator]    -{keyWord}-   .");
		}
	}
}

Kelasnya statis, mis. dia tidak bisa memiliki contoh di atas panggung. Dengan demikian, itu akan tersedia dari pemandangan mana saja kapan saja.

Semua pengelola skrip (singletones) disimpan dalam kamus Manajer . Kunci untuk setiap manajer adalah nama kelas dari manajer itu. Mungkin pendatang baru dalam pemrograman akan mengajukan pertanyaan: "Bah, tapi apa yang disimpan kamus ini , MonoBehaviour , dan semua kelas mewarisi dari Singleton ?". Ini adalah pertanyaan yang bagus, jawaban yang merupakan kunci penerapan agregator manajer otomatis dari semua kelas.

Dalam pemrograman, ada konsep konversi tipe upcasting ke kelas dasar. Karena kenyataan bahwa semua kelas di Unity mewarisi dari MonoBehaviour ,mereka dapat diterapkan ke MonoBehabiour . Oleh karena itu, kamus Manajer hanya berisi objek dari kelas MonoBehaviour .

Pertimbangkan metode kelas agregator:

void addManager<T>(T newManager)

Metode ini disebut dalam metode Sedarlah () dari kelas Singleton . Argumennya adalah variabel statis kelas instan . Selanjutnya, kunci dibuat oleh nama kelas yang menjadi milik instance , dan manajer ditambahkan ke kamus.

T getManager<T>(string callback) where T: Singleton<T>

Fungsi ini mengambil argumen string dengan nama kelas dari mana metode ini dipanggil. Ini dilakukan secara eksklusif untuk memudahkan debugging (konsol menampilkan kelas dari mana metode ini dipanggil). Contoh menggunakan metode ini di kelas AnotherMyClass :

public class AnotherMyClass: MonoBehaviour
	void Start()
	{
		string cb = GetType().ToString(); //     
		MyClass MC = ManagersAregator.getManager<MyClass >(cb);
	}

Sebuah pesan akan menggantung di konsol: " Hu ** I, redo [AnotherMyClass] Manager -MyClass- diterima."

void removeManager<T>()

Menghapus pengelola tipe T dari kamus jika ada dalam kamus.

Ringkasan


Bahkan, dari tiga fungsi kelas agregator, pengembang hanya perlu menggunakan metode getManager . Nilai tambah khusus adalah visibilitas pesan debug yang baik untuk semua kesempatan. Secara opsional, tentu saja, Anda dapat mematikannya. Saya percaya bahwa akan sangat nyaman untuk melihat pada titik waktu mana, kelas mana yang mencoba untuk mendapatkan sesuatu dan apa yang ingin ia dapatkan.

Saya harap artikel ini bermanfaat bagi Anda dan Anda menemukan sesuatu yang berguna untuk diri Anda sendiri!

All Articles