Páginas

sábado, 15 de febrero de 2014

La buena, la fea y la mala o cómo implementar una pausa en Unity




Podríamos decir que, como en la mítica película del oeste, hay tres formas de implementar una pausa en Unity, la buena, la fea y la mala.

Empezaré por la mala.

La mala

La mala es poner el timeScale a 0, lo que provoca que se pause todo Unity, es decir el sistema de animación, el de físicas, etc. Solo podremos activar y desactivar objetos o recibir eventos.


void OnPause()
{
    Time.timeScale = 0;
    menuPause.active = true;
}

void OnResume()
{
    Time.timeScale = 1;
    menuPause.active = false;

}


Es un sistema sencillo y rápido de implementar, pero como he dicho tiene la desventaja de que no se pueden usar animaciones, por lo que el menú de pausa aparece y desaparece de golpe.

La buena

La buena es que tengamos un GameManager que sepa qué objetos forman parte del juego y que sea capaz de mandarles una señal a todos los objetos del juego para que se pausen y se despausen. Cada objeto implementará la pausa a su manera y el resto del engine seguirá funcionando como siempre.

Un objeto típico haría algo así

bool paused;

void Update( float delta )
{
    // Si estamos en pausa cortamos aquí
    if (paused) { return; }


    ...

}


void OnPause()
{
    animation.Stop();
    paused = true;

}

void OnResume()
{
    animation.Play();
    paused = false;

}


Y en el GameManager


List<GameObject> gameObjectList;

void OnPause()
{

    foreach(GameObject o in gameObjectList)
    {
        o.SendMessage("OnPause");
    }

    menuPause.animation.Play("Appear");
}

void OnResume()
{
    foreach(GameObject o in gameObjectList)
    {
        o.SendMessage("OnResume");
    }

    menuPause.animation.Play("Dissapear");

}


Este sistema requiere de una buena planificación a la hora de implementar el juego, porque hay que controlar qué se pausa y qué no, pero a cambio podremos tener unos menús de pausa animados.

La fea

La solución fea es... Poner el timeScale a un número muuuuuy pequeño, con lo que todos los sistemas siguen actualizándose pero muuuuy poco, con lo que podremos usar animaciones en el menú de pausa siempre y cuando las reproduzcamos a una velocidad muuuuuuy alta.

void OnPause()
{
    Time.timeScale = 0.00000001;

    menuPause.animation.speed = 10000000; 
    menuPause.animation.Play("Appear");

}

void OnResume()
{

    Time.timeScale = 1;
    menuPause.animation.speed = 1;
    menuPause.animation.Play("Dissapear");

}


Si un jugador paciente se queda mirando a la pantalla durante tres horas igual te pillan.

Conclusión

Estos son los tres métodos que conozco. La buena es adecuada si se tiene tiempo y se pone cuidado al implementarla, la mala es adecuada si no se tiene tiempo y se busca algo seguro, y la fea... Pues... Es fea. Si es el día de entrega y se tiene que implementar una pausa deprisa y corriendo... Puede ser una solución, pero yo no me iría a dormir tranquilo.

Aunque le haya llamado así, en el mundo real la fea es la adecuada para la mayor parte de los casos :)

Más info en Unity Answers.

No hay comentarios:

Publicar un comentario