INTERFAZ DE USUARIO

Hace un tiempo ya que Unity adoptó una versión nueva de la interfaz de usuario. Ahora, podemos diseñar un montón de menús, con botones, popups y un montón de cosas con pasos muchísimos más simples. Por supuesto, si no conocen el sistema viejo no tienen un punto de comparación, pero para que se den una idea TODO se hacía por código. Ahora Unity permite arrastrar botones a la escena, que funcionan sobre un espacio propio, o sea que no están en el mismo espacio que la nave y las bullets, sino en otro en el cual las unidades son pixeles directamente, y no metros como los objetos que están en la escena. De hecho, la interfaz también está en la escena, a pesar de tener su propio sistema.

En resumen, con este sistema de interfaz de usuario podríamos mostrar el puntaje del usuario e ir actualizándolo conforme mata nuevos enemigos, o va realizando diferentes tareas. Vamos a ver cómo funciona este sistema.

Vamos a crear una escena nueva, para hacer en ella unos botones que representen el menú principal de nuestro juego. Para eso podemos presionar CTRL + N (o CMD + N en mac), o también podemos hacerlo desde el menú “File” => “New Scene“.

 

 

Vamos a guardar esta nueva escena como “MenuPrincipal” y, ya que estamos, le cambiamos el nombre a nuestra “SampleScene” por “Gameplay” para que sea más representativo. Hasta el momento usamos mucho spanglish más que nada para diferenciar algunas cuestiones como marcar bien qué cosas son del motor y cuales no. Pero lo ideal sería que usen inglés, ya que es más común dentro de la industria.

 

 

Ahora vamos a crear el fondo de nuestro menú. Busquemos en Google alguna imagen que represente un buen fondo (o si quieren poner otra también es válida). La bajamos y la arrastramos a nuestro proyecto, dentro de la carpeta “Sprites“.

A continuación vamos al menú “GameObject” => “UI” => “Canvas“.

 

 

El Canvas es básicamente el “espacio” donde todos los elementos de la interfaz de usuario se dibujan. Fuera de este Canvas ningún elemento se va a pintar en el juego. Así que antes de empezar a crear elementos debemos siempre crear un Canvas. Aunque, si no lo crean, cuando intenten poner un elemento de interfaz de usuario Unity crea el Canvas automáticamente. Si recién están empezando no les recomiendo que dejen las cosas automáticas a Unity, porque después no van a entender de dónde salen las cosas (o se les va a complicar más).

Van a notar que Unity creó dos GameObjects: “Canvas” y “EventSystem“. Este objeto se encarga de detectar inputs sobre los distintos botones y componentes de la interfaz de usuario. Por inputs entiendan no sólo los clicks del mouse, sino también los touches en un teléfono o tablet. Este objeto no es intrínsecamente necesario, ya que el Canvas funciona perfectamente sin este objeto, sólo que no detectará inputs. Si tienen una interfaz que no necesita detectar inputs sobre el canvas, como barras de energía, puntaje y demás, no es necesario que este objeto esté.

 

 

Van a ver que cada uno tiene distintos componentes. Cada uno para una funcionalidad en concreto. Los que más interesan para esta tarea son los del Canvas. Si hacen zoom en la ventana “Scene” van a notar que hay un recuadro todavía más grande. Ese cuadrado (o rectángulo según la ocasión), representa el área de trabajo del Canvas. Van a notar seguramente que esa área es muchísimo más grande que el cuadrado donde trascurre el juego. Esto no tiene mucha importancia, ya que un espacio es en píxeles y otro en metros.

A continuación vamos a crear un elemento de imagen para poner nuestro fondo. Para eso hacemos “Click Derecho (sobre el canvas)” => “UI” => “Image“.

 

INSERTANDO UN FONDO

 

Van a notar que aparece un cuadrado blanco sobre el Canvas que en apariencia es mucho más grande que el área de la cámara, pero si lo ven en la pestaña “Game” es bastante más chico (tranquilos, ya se van a acostumbrar).

 

 

Seleccionen la imagen y van a ver sus propiedades en la ventana “Inspector“. Van a notar que en lugar del componente Transform utiliza otro llamado RectTransform. Básicamente es su equivalente dentro del sistema de interfaz de usuario de Unity. Las propiedades que vayamos modificando son en píxeles en lugar de en metros. Así que el (0, 0) en el componente Transform no es el mismo que el (0, 0) en RectTransform.

 

 

El cuadrado blanco no es una imagen, sino que está usando la propiedad “Color” que tiene la imagen (que se puede cambiar, por cierto). Noten también que tiene una propiedad llamada “Source Image“. Esta es la propiedad a la que tenemos que arrastrar la imagen de nuestro fondo. Haganlo y vean qué pasa.

 

 

Como habrán notado, la imagen se adapta al componente. Así que si modificamos el ancho y alto del componente podemos cambiar sus dimensiones. Pero tengan en cuenta que modificar el ancho y alto no es lo mismo que modificar la escala. Cuando ustedes estiran una imagen usando el botón de escalar (o cambiando los valores de la propiedad “scale“), lo que están haciendo básicamente es cambiar el número por el cual se va a multiplicar al ancho y al alto. Yo les recomendaría que siempre tengan en cuenta esto antes de agrandar o achicar una imagen.

El componente RectTransform tiene un botón que nos permite setear la forma en la cual este componente se transforma. O sea, podemos controlar desde dónde se mueve y/o cambia sus dimensiones, si es con respecto a los márgenes de la pantalla o no, etc. Por ejemplo, en el caso de nuestra imagen de fondo, si sabemos que nuestro juego va a ser de un tipo de resolución fija, como 16:9, podemos hacer que la imagen se adapte a los bordes de nuestra pantalla siempre.

 

 

Sin ir demasiado profundo en el tema, básicamente con estos botones cambiamos la forma en la cual se ancla el objeto. Por ejemplo, si seleccionamos su punto de anclaje arriba a la izquierda, esto nos indica que cuando su posición sea (0, 0), el objeto estará arriba a la izquierda. Si lo anclamos arriba a la derecha, esto significa que cuando su posición sea (o, o), entonces estará arriba a la derecha. En palabras más cortas, lo que indica es cuál será su posición cuando esté en (0, 0)

También podemos cambiar el anclaje en sus puntas, y en lugar de modificar el ancho y el alto estaríamos modificando qué tan lejos de los bordes de la pantalla está. Si modificamos los anclajes de las puntas, podríamos decirle que al setear su posición en:

  • Left = 0.
  • Top = 0.
  • Right = 0.
  • Bottom = 0.

El objeto se fije a los bordes de la pantalla. Cada seteo debería ir acorde al propósito que tenga cada uno. Observen la siguiente imagen para ver una demostración:

 

 

Observen también que, tal y como lo indica en la parte de arriba del cuadro, si presionan SHIFT, ALT (“option” en mac), o ambas teclas, pueden modificar distintas partes del objeto.

Otra cosa que pueden notar es que si ustedes cambian las dimensiones de la cámara, o sea, si la resolución no fuera 16:9 y fuera 9:16 (como un celular parado), la imagen se va a empezar a escalar. Es por esto también que les decía que elijan la mejor opción en base a lo que quieran lograr. Si saben que su relación de aspecto va a ser siempre la misma, podemos desde ahora indicarle eso a Unity para que ustedes vayan viendo resultados más fieles al resultado final. Pueden ir a la ventana “Game” y arriba a la izquierda modificar la relación de aspecto o incluso crear una propia.

 

 

Vean cómo la cámara ahora se ajusta a esa relación de aspecto. Esto es útil para cuando quieren probar su juego en distintas resoluciones y/o formatos. Por ejemplo, si quieren que su juego sea para un celular, probablemente quieran que la interfaz sea diferente cuando el celular está acostado que cuando está parado.

Estos ajustes van a afectar directamente a todos los componentes de la UI. Noten que el componente Canvas es el que decide en términos finales cómo se van a comportar los objetos que tenga dentro. Así que además de cambiar la relación de aspecto, también deberían tener distintos seteos en este Canvas para ajustarse del todo.

 

 

Mirando ambas imágenes de arriba pueden notar las diferencias entre la relación de aspecto que viene predeterminadamente y la 16:9, que para PC suele ser la más común.

 

FUNCIONAMIENTO DE LOS BOTONES

Los botones no tienen demasiada ciencia y agregarles funcionalidad es bastante sencillo. Lo que vamos a hacer para empezar es crear un botón en el centro del Canvas. Si se animan a hacerlo ustedes en base a lo que acabamos de ver sobre Canvas, sería una buena práctica. Haganlo y después vean la solución!!

 

Primero creamos el botón:

Con los seteos que tiene de manera predeterminada el botón estará en el centro cuando lo pongan en (0, 0), así que no hace falta tocar esta configuración.

 

Si quieren cambiar el texto que muestra el botón, sólo ábranlo y se van a dar cuenta que adentro tiene un GameObject que tiene un componente Text que nos permite modificarlo.

 

 

Noten además que pueden cambiar cómo se ve ese texto, como el justificado, color, tipografía, etc. Así que ponganle los seteos que gusten. Una vez puestos, pueden ponerle “Play” al juego y van a ver que la funcionalidad del botón ya está hecha, puesto que viene incluida de fábrica. 

Si seleccionan el botón y van a la ventana “Inspetor” pueden cambiar el comportamiento del mismo al pasar el mouse por arriba o presionarlo. Noten que tiene opciones como:

  • Normal => Color cuando el botón está sin seleccionar ni nada.
  • Highlighted Color => Color al pasarle el mouse por arriba.
  • Pressed Color => Color al presionarlo.
  • Disabled Color => Color mientras está deshabilitado.

 

 

Una vez configurada la visual del botón, ya estamos listos para darle funcionalidad. Para ello, vamos a crear un script y le vamos a poner de nombre MainMenu (de nuevo, el nombre es completamente opcional, ponganle el que quieran). Este script vamos a ponerlo en un GameObject vacío, ya que sólo queremos que tenga una funcionalidad en la escena. O sea, no que controle a un objeto sino a la escena entera.

Recuerden que para crear un GameObject vacío, sólo tienen que ir al menú “GameObject” => “Create empty“.

 

 

Como este script se va a encargar de controlar la escena del menú principal, lo que vamos a hacer es crearle una funcionalidad básica para que, por ejemplo, pueda ir de una escena a la otra. Para esto vamos a crearle un bloque de código y lo vamos a llamar “CargarEscena” (o como les guste).

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MainMenu : MonoBehaviour
{
    // Use this for initialization
    void Start ()
    {
        
    }
    
    // Update is called once per frame
    void Update ()
    {
        
    }
    
    public void CargarEscena()
    {
        Debug.Log("CARGAR ESCENA!!");
    }
}

 

Hecho este bloque de código… ¿Cómo hacemos para que el botón pueda ejecutarlo? Para esto seleccionamos el botón, y en la parte donde dice “On Click” hacemos click en el botón “+“.

 

 

Luego de esto nos aparecerá un bloque donde podemos arrastrar algo. Lo que vamos a arrastrar es el objeto que acabamos de crear, que contiene el script MainMenu. Hacer esto le indica a Unity que el bloque de código que se va a ejecutar cuando hagamos click en el botón lo va a sacar del objeto que arrastremos.

 

 

Al arrastrarlo lo que vamos a ver es un menú desplagable que dice “No Function“. Hagan click en el menú y van a ver que al desplegarse muestra todos los componentes que tenga el GameObject que hayan arrastrado. Y si se paran en uno de los componentes que figuran ahí, van a ver que nos muestra todos los bloques de código que pueden ser invocados. El que seleccionen se va a invocar al hacer click en el botón. Seleccionemos el que acabamos de crear.

 

 

Ahora prueben el proyecto y hagan click en el botón para ver lo que ocurre. Verán que aparece el texto que le pusimos en la consola. Ahora… ¿Cómo hacemos que cargue la otra escena? Para esto, volvemos al script y tenemos que escribir lo siguiente:

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; //ESTO ES IMPORTANTE!!

public class MainMenu : MonoBehaviour
{
    // Use this for initialization
    void Start ()
    {
        
    }
    
    // Update is called once per frame
    void Update ()
    {
        
    }
    
    public void CargarEscena()
    {
        SceneManager.LoadScene("Gameplay");
    }
}

Noten que es necesario escribir una línea de código arriba de todo, que es la que trae la librería para controlar las escenas de Unity. Luego de eso, prueben el código. Van a notar que les tira un error. El mismo dice algo como esto:

 

 

Este error se debe a que nos faltó un pequeño paso antes. Unity nos indica con esto que en la configuración de las escenas del juego, jamás agregamos a la lista la escena que queremos cargar. Unity necesita tener en una lista todas las escenas que se van a compilar y que van a estar disponibles. Así que vamos a agregar las dos escenas. Para esto hacemos click en “File” => “Build Settings” y arrastramos nuestras dos escenas al cuadro que está más arriba.

 

 

 

Prueben ahora y debería funcionar todo OK!! Así que ya tenemos un menú principal bastante simplón, pero de acá en adelante ya depende de la creatividad que quieran ponerle. Por supuesto hay muchísimas más cosas de Unity, pero creo que esto es más que suficiente para arrancar. Vayan experimentando con diferentes cosas. Prueben, equivoquense, hagan juegos muuuuuy simplones para empezar y ganar un poco de “cancha” con el motor, y cualquier cosa pregunten!!

Conforme vaya teniendo tiempo voy a ir subiendo más cosas y actualizando el post.