Unity3D: agrégateur de gestionnaire de script automatique

introduction


Cet article se concentrera sur un type d'organisation d'interaction entre les gestionnaires de scripts (appelés singletones), et en particulier, l'utilisation d'une classe d'agrégateur distincte qui contient des références à tous les gestionnaires d'instances. L'idée de créer une classe d'agrégateur m'est venue à l'esprit après avoir lu cet article .

Tâches


J'en suis venu à la conclusion qu'il est extrêmement gênant d'incorporer les gestionnaires dans la classe des agrégateurs avec leurs propres stylos à chaque fois. Lors de la création d'un nouveau gestionnaire, vous devrez ouvrir la classe d'agrégateur et apporter des modifications. Avec suffisamment d'expérience, vous pouvez automatiser de tels processus fastidieux. Ainsi, les tâches étaient définies: création automatique de singletones et de leur collecteur automatique.

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

L'implémentation singleton classique dans Unity utilise la variable statique d' instance . La méthode Awake () vérifie si l' instance est définie . Sinon, nous obtenons une référence à l'instance de classe en utilisant le mot-clé this . Mais depuis dans une implémentation particulière, une variable «modèle» de classe T est utilisée, elle ne peut pas être utilisée. Mais nous pouvons facilement obtenir le composant T de l'objet sur lequel le script se bloque. Si l' instance est définie, elle doit être détruite. Ainsi, l'objet sera toujours sur scène en un seul exemplaire.

Dans la méthode Awake ()un nouvel élément est ajouté à la classe d'agrégateur et dans la méthode OnDestroy () , l' élément est supprimé de la classe d'agrégateur.

La création d'un singleton de la classe MyClass est la suivante:

public class MyClass: Singleton<MyClass>

Si vous devez utiliser la méthode Awake () dans la classe MyClass , vous devez utiliser le mot - clé base ( plus sur la base et l'héritage ):

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

Agrégateur de classe


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

La classe est statique, c'est-à-dire il ne peut pas avoir d'instance sur scène. Ainsi, il sera disponible à partir de n'importe quelle scène à tout moment.

Tous les gestionnaires de scripts (singletones) sont stockés dans le dictionnaire des gestionnaires . La clé de chaque gestionnaire est le nom de classe de ce gestionnaire. Peut-être que les nouveaux arrivants en programmation poseront la question: «Bah, mais qu'est-ce que ce dictionnaire stocke MonoBehaviour , et toutes les classes héritent de Singleton ?». C'est une bonne question, dont la réponse est la clé de la mise en œuvre d'un agrégateur automatique de gestionnaires de toutes classes.

En programmation, il y a le concept de conversion de type upcasting en classe de base. Étant donné que toutes les classes dans Unity héritent de MonoBehaviour ,ils peuvent être appliqués à MonoBehabiour . Par conséquent, le dictionnaire des gestionnaires contient uniquement des objets de la classe MonoBehaviour .

Considérez les méthodes de la classe agrégateur:

void addManager<T>(T newManager)

Cette méthode est appelée dans la méthode Awake () de la classe Singleton . L'argument est une variable statique de la classe d' instance . Ensuite, une clé est créée par le nom de la classe à laquelle appartient l' instance et le gestionnaire est ajouté au dictionnaire.

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

La fonction prend comme argument une chaîne avec le nom de la classe d'où la méthode est appelée. Cela se fait exclusivement pour un débogage pratique (la console affiche la classe à partir de laquelle la méthode est appelée). Un exemple d'utilisation de cette méthode dans la classe AnotherMyClass :

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

Un message va se bloquer dans la console: " Hu ** I, refaire [AnotherMyClass] Manager -MyClass- reçu."

void removeManager<T>()

Supprime un gestionnaire de type T du dictionnaire s'il est contenu dans le dictionnaire.

Sommaire


En fait, parmi les trois fonctions de la classe agrégateur, un développeur n'a besoin que d'utiliser la méthode getManager . Un avantage particulier est la bonne visibilité des messages de débogage pour toutes les occasions. En option, bien sûr, vous pouvez les désactiver. Je pense qu'il sera très pratique de voir à quel moment, quelle classe essaie d'obtenir quelque chose et ce qu'elle essaie d'obtenir.

J'espère que cet article vous a été utile et que vous avez découvert quelque chose d'utile pour vous!

All Articles