Comunidad orientada al desarrollo de videojuegos

Unity3D Patrón Singleton

Singleton es un patrón cuyo propósito es asegurarse que solo exista una instancia de una clase y proporciona un acceso fácil y global a la clase. Este patrón nos puede venir bien para variables globales del juego como settings o datos del un usuario, también podemos usarlo para crearnos un gestor de audio de todo nuestro juego, etc…

El patrón es bastante sencillo, se trata de una clase con un constructor privado que expone una única instancia de si misma para acceder a ella. En este caso, no te deja hacer news fuera ni heredar de ella.

public sealed class MySingleton
{
private static readonly MySingleton instance = new MySingleton();

public static MySingleton Instance
{
get
{
return instance;
}
}

static MySingleton() { }
private MySingleton() { }

}

Bien, esta es la manera de hacerlo de libro, que es muy correcta, pero si quiero que mi clase herede de MonoBehaviour para que se comporte como uno de los demás scripts de Unity, esta solución no es valida, ya que las cases heredadas de MonoBehaviour no permiten hacer news, va a funcionar pero no correctamente. Así pues, vamos a transformarlo un poco para que sea compatible con MonoBehaviour.

public class MySingleton : MonoBehaviour
{
private static MySingleton instance;

public static MySingleton Instance
{
get
{
if (instance == null)
{
GameObject mySingletonObject = new GameObject("MySingletonObject");
DontDestroyOnLoad(mySingletonObject);
instance = mySingletonObject.AddComponent<MySingleton>();
}
return instance;
}
}
}

Hemos añadido la herencia de MonoBehaviour y le hemos quitado el sealed a la clase, va a funcionar como un script mas de Unity. Puesto que ahora vamos a inicializar la instancia en el get del Singleton, le hemos quitado el readonly para poder asignárselo.

Dentro del get hacemos lo mas importante, lo primero es saber si ya se ha inicializado la instancia del Singleton, si es así, simplemente devolvemos esa instancia. Pero si aun no lo hemos inicializado, nos creamos un GameObject que va a contener nuestro Singleton, necesitamos este GameObject para decirle que no se destruya mediante DontDestroyOnLoad y que nuestro Singleton perdure durante toda la ejecución del juego, por último, le añadimos el Singleton como un componente y guardamos la instancia del mismo.

Ya tenemos hecho todo el grueso de nuestro Singleton. ¡Ahora nos toca sacarle partido! Le vamos a dar algo de funcionalidad para que veamos lo cómodo que es acceder a este tipo de clases desde Unity3D. Le añadimos el método HazAlgo al final de la clase.

public void HazAlgo()
{
Debug.Log("Estoy haciendo algo...");
}

Para acceder a nuestro método, no tenemos mas que usar el espacio de nombres para acceder a la instancia interna de la clase y desde ahí, acceder a todos los métodos y propiedades que tengamos en la clase.

Si accediéramos desde otro Script seria algo así:

public class singletonTest : MonoBehaviour {

// Use this for initialization
void Start () {
MySingleton.Instance.HazAlgo();
}
}

Como veis, es muy fácil, muy limpio y sencillo a la vez.

Me gustaría recalcar, que al ser un MonoBehaviour, podemos usar los métodos usuales de cualquier Script de Unity. De esta forma, si accedemos el método Awake, por ejemplo, podemos usarlo para inicializar los valores necesarios. Aunque se cargue la escena en la que vamos a usar nuestro Singleton, hasta que no se hace la primera llamada, no se genera el GameObject y no se llama al método Awake. Vamos a comprobarlo:

void Awake()
{
Debug.Log("Inicializando...");
}

 

Os dejo un paquete con 2 escenas listas para probar el código que hemos visto, con el Espacio accedemos al Singleton y con el Enter cambiamos de escena, veréis que independientemente de la escena en la que accedamos al Singleton, se creará por primera vez, pasando por el Awake, y todas las demás veces accederá a la instancia, aunque cambiemos de escena no se volverá a crear.

https://db.tt/KOTLBeYr

 

Referencias:

http://msdn.microsoft.com/es-es/library/bb972272.aspx

http://kartones.net/blogs/jadengine/archive/2009/05/20/el-patr-243-n-singleton-en-c.aspx

, , ,

Leave a Reply