Unity3D: Automatischer Script Manager-Aggregator

Einführung


Dieser Artikel konzentriert sich auf eine Art der Organisation der Interaktion zwischen Skriptmanagern (als Singletones bezeichnet) und insbesondere auf die Verwendung einer separaten Aggregatorklasse, die Verweise auf alle Instanzmanager enthält. Die Idee, eine Aggregatorklasse zu erstellen, kam mir nach dem Lesen dieses Artikels in den Sinn .

Aufgaben


Ich kam zu dem Schluss, dass es äußerst unpraktisch ist, Manager jedes Mal mit ihren eigenen Stiften in die Aggregatorklasse zu hämmern. Wenn Sie einen neuen Manager erstellen, müssen Sie die Aggregatorklasse öffnen und Änderungen vornehmen. Mit genügend Erfahrung können Sie solche langwierigen Prozesse automatisieren. So wurden die Aufgaben festgelegt: Automatische Erstellung von Singletones und deren automatischem Kollektor.

Klasse-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>();
	}
}

Die klassische Singleton Implementierung in Unity verwendet die Instanz statische Variable . Die Awake () -Methode prüft, ob eine Instanz definiert ist . Wenn nicht, erhalten wir mit dem Schlüsselwort this einen Verweis auf die Klasseninstanz . Aber seit in einer bestimmten Implementierung, ein „Schablone“ Variable der Klasse T verwendet wird, diese nicht verwendet werden kann. Wir können die T- Komponente jedoch leicht von dem Objekt abrufen, an dem das Skript hängt. Wenn eine Instanz definiert ist, muss sie zerstört werden. Somit befindet sich das Objekt immer in einer einzigen Kopie auf der Bühne.

In der Awake () -MethodeDer Aggregatorklasse wird ein neues Element hinzugefügt, und in der OnDestroy () -Methode wird das Element aus der Aggregatorklasse entfernt.

Das Erstellen eines Singletons der MyClass- Klasse lautet wie folgt:

public class MyClass: Singleton<MyClass>

Wenn Sie die Awake () -Methode in der MyClass- Klasse verwenden müssen , müssen Sie das Basisschlüsselwort verwenden ( weitere Informationen zu Basis und Vererbung ):

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

Klassenaggregator


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}-   .");
		}
	}
}

Die Klasse ist statisch, d.h. Er kann keine Instanz auf der Bühne haben. Somit ist es jederzeit in jeder Szene verfügbar.

Alle Skriptmanager (Singletones) werden im Manager- Wörterbuch gespeichert . Der Schlüssel für jeden Manager ist der Klassenname dieses Managers. Vielleicht werden Neulinge in der Programmierung die Frage stellen: "Bah, aber was speichert dieses Wörterbuch MonoBehaviour und alle Klassen, die von Singleton erben ?". Dies ist eine gute Frage, deren Antwort der Schlüssel zur Implementierung eines automatischen Aggregators von Managern aller Klassen ist.

In der Programmierung gibt es das Konzept der Upcasting- Typ-Konvertierung in eine Basisklasse. Aufgrund der Tatsache, dass alle Klassen in Unity von MonoBehaviour erben ,Sie können auf MonoBehabiour angewendet werden . Daher enthält das Manager- Wörterbuch nur Objekte der MonoBehaviour- Klasse .

Betrachten Sie die Methoden der Aggregatorklasse:

void addManager<T>(T newManager)

Diese Methode wird in der Awake () -Methode der Singleton- Klasse aufgerufen . Das Argument ist eine statische Variable der Instanzklasse . Als Nächstes wird ein Schlüssel mit dem Namen der Klasse erstellt, zu der die Instanz gehört , und der Manager wird dem Wörterbuch hinzugefügt.

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

Die Funktion verwendet als Argument eine Zeichenfolge mit dem Namen der Klasse, von der aus die Methode aufgerufen wird. Dies erfolgt ausschließlich zum bequemen Debuggen (die Konsole zeigt die Klasse an, von der aus die Methode aufgerufen wird). Ein Beispiel für die Verwendung dieser Methode in der AnotherMyClass- Klasse :

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

In der Konsole hängt eine Meldung: " Hu ** I, [AnotherMyClass] Manager - MyClass- Received wiederholen."

void removeManager<T>()

Löscht einen Manager vom Typ T aus dem Wörterbuch, wenn er im Wörterbuch enthalten ist.

Zusammenfassung


Von den drei Funktionen der Aggregatorklasse muss ein Entwickler lediglich die Methode getManager verwenden . Ein besonderes Plus ist die gute Sichtbarkeit von Debug-Meldungen für alle Gelegenheiten. Optional können Sie sie natürlich ausschalten. Ich glaube, dass es sehr bequem sein wird zu sehen, zu welchem ​​Zeitpunkt, welche Klasse versucht, etwas zu bekommen und was sie versucht zu bekommen.

Ich hoffe, dieser Artikel hat Ihnen geholfen und Sie haben etwas Nützliches für sich herausgefunden!

All Articles