lunes, 21 de agosto de 2017

Tutorial de plataformas 2D en Unity (IX)








12.       Implementando la puntuación:



En este capítulo aprenderemos a crear un sistema de puntuación para nuestro juego.

En primer lugar, vamos a crear un marco sobre el que se dibujarán los números e iconos que vamos a utilizar, el diseño es cosa vuestra, para hacer el tutorial yo dejaré un marco negro en la parte superior.











Lo guardamos como “Marco.png” y lo arrastramos hasta nuestra carpeta “Sprites”.

Una vez hecho esto, en el menú “Hierarchy” crearemos un GameObject vacío que llamaremos “Persistente” y también un script (en la carpeta “Scripts”) con el mismo nombre.

Voy a hacer un breve repaso sobre las funciones predefinidas con las que se crea cualquier nuevo script.

En la función “Update”, se ejecutaban todas las instrucciones que escribiésemos una vez en cada frame, mientras que lo que escribamos en la función “Start” se ejecutará una única vez al acceder al script.

(Si escribimos algo en la función “Start” y algo en la función “Update”, primero se ejecutará la función “Start” y luego el programa pasará a ejecutar la función “Update”).

Vamos a descubrir la función “Awake”, cuya funcionalidad es la misma que la función “Start” con la diferencia, de que el orden de ejecución en el script es (Awake > Start > Update).

La idea de utilizar la función “Awake” es decirle a nuestro juego, que lo primero que ejecute al iniciarse, sea lo que escribamos en esta función.











private void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }


Unity, cuando cambia de escena, destruye todos los objetos de la escena anterior, para luego crear los nuevos objetos de la siguiente escena que carguemos.
Dentro de “Persistente” colocaremos nuestra puntuación.

Esta línea de código lo que hace es evitar que el programa destruya el objeto al que hemos asignado este script. Para de este modo, conseguir que Unity no destruya nuestra puntuación al cambiar de escena.  (Si no lo hacemos así, la puntuación se pondría a cero cada vez que cambiemos de fase).

Cuando tengamos el script. Volvemos a Unity para asignárselo a nuestro objeto “Persistente”. Más adelante creamos un “Canvas” (recordad que un “Canvas” es el método con el que hacemos distintos tipos de menús con texto o iconos, tal como hicimos cuando creamos el menú que aparece al iniciar el juego).











Recordad que para escalarlo a pantalla completa había que seleccionar la siguiente opción:











No os preocupéis porque el canvas sea inmenso en comparación con nuestra escena.

Dentro del “Canvas”, creamos una “Image” y la colocamos en la parte superior de la pantalla. Luego a esa imagen le asignaremos el marco que creamos antes.











Vamos a usar un script bastante más complejo, pero no os asustéis os voy a dejar el enlace para que lo descarguéis y lo copiéis a vuestra carpeta “Scripts”, si queréis abrirlo en el interior os viene una descripción de lo que hace (es un sistema de comunicación entre objetos).


Podéis encontrar información sobre este script y su código fuente aquí: 


Y podéis descargarlo del siguiente enlace (no hay que asignarlo a ningún objeto, simplemente haremos una llamada a este script desde otro que controlará la puntuación):


Ahora necesitamos crear un script que nos lleve la puntuación que tenemos en el juego. Por lo que nos vamos a la carpeta “Scripts” y creamos nuestro script “Puntuacion”.
















Primero declaramos un número (int significa que es entero) para que lleve la puntuación.

En la función “Start” haremos la llamada al script “NotificationCenter”:

NotificationCenter.DefaultCenter().AddObserver(this, "SumaPuntos");

La línea hace que el programa añada a “NotificationCenter” el resultado de la función que vamos a crear a continuación llamada “SumaPuntos”.

void SumaPuntos (Notification notificacion)

    {
        int Puntos = (int)notificacion.data;
        puntuacion = puntuacion + Puntos;
    }

En esta función vamos a hacer que el número entero Puntos se asigne a la notificacion.data como un número entero. (En otras palabras, especificamos que el dato que vamos a añadir al NotificationCenter es un número entero).

puntuacion = puntuacion + Puntos;

“puntuacion” empieza valiendo cero por lo que la ecuación sería “0 = 0 + 0”, en el momento en que “puntuacion” sea “1” su valor se irá actualizando.

Ahora vamos a salir del script y nos vamos a dibujar (o descargar) los ítems que queramos que sean los que nos aporten los puntos. En mi caso he encontrado las monedas de Mario, por lo que las implementaré en un Prefab como hicimos con el personaje.

















Cuando tengamos ya la moneda, asignamos el tag “Player” a nuestro personaje y creamos un script llamado “Item” que asignaremos al prefab de la moneda y en el que escribiremos lo siguiente:










Declaramos un número entero público, que será la cantidad de puntos que sume la moneda.


private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Player")
        {
            NotificationCenter.DefaultCenter().PostNotification(this, "SumaPuntos", PuntosMoneda);
            Destroy(gameObject);
        }


    }



Luego creamos una función que hace lo siguiente:

Si un objeto con tag “Player” entra en el collider2D con la función Trigger activada, realiza una llamada al script “NotificationCenter” para decirle a “SumaPuntos” el valor de PuntosMoneda.

Luego destruye el objeto que tenga este script asignado, en nuestro caso, la moneda.










Si queremos, podemos declarar también una variable pública “AudioClip” para reproducir un sonido cuando cojamos la moneda.











AudioSource.PlayClipAtPoint(Coin, Camara.transform.position);


Lo que hace esta línea es reproducir el clip de audio “Coin” en la posición donde esté la cámara. (Esto se hace así porque la cámara tiene un componente “Audio Listener”, que es, por así decirlo, donde tendríamos puestos nuestros oídos, de manera que si no reproducimos el sonido en la posición donde esté la cámara el sonido se escucharía demasiado lejos, incluso llegando a no oírse). En la imagen podéis ver el “Audio Listener” en la cámara:











También hay que decir que utilizamos la línea:


AudioSource.PlayClipAtPoint(Coin, Camara.transform.position);


La cual es distinta a la que usamos para el salto de Mario:


GetComponent<AudioSource>().Play();


Este cambio lo hemos hecho (aparte de para que veáis varios modos de reproducir sonidos), porque como el objeto “Moneda” será destruido en cuanto colisionemos con él, con “GetComponent”, el objeto se destruye antes de reproducir el sonido, por lo que no se oiría. 

Os animo a que hagáis la prueba con los dos modos, es una forma genial de aprender.

Volvemos al proyecto, y en el Canvas que habíamos creado (donde pusimos el marco en la parte superior) y dentro del Canvas vamos a crear dos “Text” (si queremos podemos descargarnos una nueva fuente como hicimos con el menú principal). A uno de ellos lo llamaremos “Marcador” y en el apartado “text” ponemos lo que queramos que se muestre (en mi caso, “Monedas”) y al otro lo llamaré “Numero” y en texto pondré “100” porque es el máximo de monedas que tendremos (al llegar a 100 el número se reiniciará y nuestras vidas aumentarán en 1). Cuando los tengáis ajustad el tamaño de letra, el color, la posición y la fuente que queramos, al final quedará algo similar a la imagen.











Cuando esté todo configurado a nuestro gusto, abrimos el script “Puntuacion”.










Importante importar la librería “UnityEngine.UI” para ello copiad la línea que he resaltado en la imagen al principio del script, ya que esta librería es la que nos va a permitir trabajar con los componentes “UI” tales como el texto.

Acto seguido declaramos una variable pública “Text” que llamaremos “Marcador”.
Luego vamos a crear nueva función que llamaremos ActualizarMarcador (será a la función que llamemos para ir actualizando la puntuación en nuestra pantalla).


  void ActualizaMarcador()
    {
        Marcador.text = puntuacion.ToString();
    }


Esto quiere decir que transformes el número puntuacion (recordad que lo declaramos como número entero) en texto (ahora Unity cuando vea un número, lo tratará como cualquier otro carácter del teclado, en vez de tratarlo como una cifra), y luego este texto se lo asignes al texto “Marcador”.

Una vez hecho esto vamos a llamar a la función una vez al inicio de la partida (en la función “Start” para que reinicie nuestro marcador, y otra cada vez que sumemos algún punto (en la función “SumaPuntos”). La llamada se hace con la siguiente línea:


ActualizaMarcador();


Al final el script quedará así:










Cuando acabemos guardamos el script, se lo asignamos en Unity a nuestro Canvas y después asignamos el “Text” que creamos antes (el de la puntuación) al script tal como en la imagen.










Si probamos la partida veremos que ya tenemos puntuación.
















Esto es todo por ahora, recordad que podéis preguntar cualquier duda tanto en los comentarios, como en Twitter: @Lepra_Games o en la página de Facebook: Lepra Games.

No hay comentarios:

Publicar un comentario