Está en la página 1de 13

Unidad III - UI

Contenido de la unidad
1. Propiedades de la Cámara
a. UI En World Space vs Screen Overlay
b. Visualización de elementos que no son de UI dentro la UI
2. UI Adaptable a las distintas resoluciones
a. Propiedades del componente de Imagen
i. Filled / Sliced
b. Fuentes, propiedades del componente de Text
i. Text Mesh Pro
3. Correcto Manejo de Canvas/Paneles
a. Multiple Canvas
b. Sorting Layer
4. Horizontal, Grid, Vertical Layout
5. Scroll View
6. Máscaras

Propiedades de la Cámara
Al momento de trabajar con la UI de Unity, vemos que nuestro Canvas no necesariamente está
utilizando la cámara para renderizarse, de hecho podemos eliminar la cámara principal (o
cualquier cámara) y la UI seguirá visualizando en pantalla. Esto es porque en cierta forma el
Canvas (de acuerdo al modo de renderización) actúa en cierta forma como una “cámara”.

Hay un par de configuraciones que son necesarias conocer al momento de trabajar con UI,
referidas al Canvas.
Render Mode. Tenemos 3 opciones para elegir.
La descripción detallada de que significa cada modo se puede encontrar en la documentación
de Unity, https://docs.unity3d.com/es/2018.4/Manual/UICanvas.html sin embargo a modo de
resumen podemos decir que:

● Screen Space - Overlay: Es el modo por defecto. La UI se visualiza encima de cualquier


elemento, no tiene en cuenta la cámara del juego.
● Screen Space - Camera. Similar al anterior, pero la UI se posiciona sobre la cámara
asignada y la UI se verá afectada por la configuración de esta cámara.
● World Space. El Canvas se comporta como cualquier objeto 3D.

A modo de ejemplo, Screen Space - Overlay sería nuestra UI normal, pero si necesitamos
integrar elementos de nuestro gameplay, como por ejemplo un bestiario donde nos gustaría ver
las unidades del juego animadas (2D o 3D) como parte de la UI, utilizando Sprite Renderer o
Mesh Renderer, entonces deberíamos utilizar un Canvas que se visualize en Screen Space -
Camera.
World Space, son para elementos de UI que se van a visualizar dentro del mundo del juego
(ejemplos barras de vida de unidades).

Ejemplo de Screen Space - Camera.

Es importante tener en cuenta que Screen Space - Overlay se va a visualizar SIEMPRE


arriba de cualquier otro componente de cámara, por lo tanto si nuestra UI va a mezclar UI
comunes con UI que requieren visualizar elementos de gameplay, conviene armar todas las
UI con Screen Space - Camera, para evitar problemas de visualización.

UI Adaptables
Seguramente han pasado por la situación en que la UI se ve perfecta, en el editor, y hacen el
build a la plataforma de destino y la UI se ve demasiado chica o grande o con proporciones
incorrectas.

Setup Inicial

En el canvas uno de los componentes principales al momento de hacer que nuestra UI se


adapte a las distintas resoluciones es el Canvas Scaler.

Por defecto el componente viene con la propiedad UI Scale Mode en Constant Pixel Size.
Esto quiere decir que nuestros elementos del Canvas van a tener siempre el mismo tamaño,
independiente del tamaño de la pantalla.

Algo similar sucede con la opción Constant Physical Size, pero además del tamaño de la
pantalla, tiene en cuenta la resolución de la misma.

Por lo tanto, para que nuestro Canvas se adapte al tamaño y resolución de la pantalla, la
opción que debemos elegir es Scale with Screen Size.

Al momento de seleccionar la opción Scale With Screen Size, aparecen nuevas propiedades
que nos van a ayudar a configurar como el Canvas se va a comportar con distintas
resoluciones.

La primera propiedad es Reference Resolution, como su nombre lo indica es simplemente una


referencia sobre la cual Unity va a poder realizar cálculos acerca de cómo tienen que
comportarse los elementos. Si la resolución es mayor a la de referencia entonces agrandará los
elementos, por el contrario si es menor, reducirá el tamaño de los mismos.
Screen Match Mode, esta propiedad nos ayudará a determinar el modo que usará el Canvas
para escalar la interfaz en caso que la resolución no sea la misma que la resolución de
referencia.

Entre las propiedades encontramos, Match Width or Height, en este caso escalara el canvas
de acuerdo al ancho o alto de la pantalla a cubrir. Expand En este caso no sirve para expandir
el canvas, sin embargo el límite inferior del expand es el valor de la resolución de referencia,
por lo tanto si ponemos expand y cómo Reference Resolution, pusimos un valor de 1920x1080,
entonces como mínimo nuestra UI tendrá dicha resolución. Shrink, a diferencia del método
anterior comenzará a cortar el canvas horizontal o verticalmente, teniendo como límite superior
el puesto en el valor de referencia.

En mobile el método por defecto a utilizar es Match Width or Height. Con respecto al Match, lo
ideal es plantear cómo queremos que se vea nuestro juego y adaptar el slider de Match para
ese punto (landscape = width, portrait = height).

Reference Pixels Per Unit. Es importante que este valor sea el mismo que utilizamos al
momento de importar los sprites a utilizar en la UI. Si elegimos importar el Sprite con Pixels Per
Unit = 1, entonces el píxel de referencia del canvas debe ser 1.

Una vez hemos seteado el canvas de forma correcta, lo que nos queda es simplemente ubicar
los elementos en la UI y dependiendo los valores de referencia podemos utilizar los tamaños
reales o no de los gráficos.

Por ejemplo, si nuestro equipo de diseño preparó la interfaz para una resolución de 1920x1080,
entonces lo ideal sería que nuestro canvas tenga una resolución de referencia de 1920x1080,
match width y pixel per unit el mismo que el sprite 2D (que debería ser 1, para evitar cálculos
complejos).

De esta forma si queremos armar un menú y sabemos que el menú está separado 100 px de la
derecha, entonces ponemos el anchor a la derecha y corremos el menú 100 unidades de unity.
Logrando un traspaso casi 1:1 desde photoshop a Unity.

Propiedades del componente de Imagen


Si bien, la magia del autoscale lo realiza el componente anteriormente visto, hay algunas
propiedades en las imágenes que nos pueden ayudar a reutilizar sprites en distintas UI.

Image Type: Sliced.


Hemos visto que cuando ponemos una imagen en UI, el campo Image Type, tiene distintas
opciones, una de esas opciones (y la más interesante al momento de armar UI, especialmente
paneles) es el valor sliced.

Este valor hace uso del método 9 slice scaling (https://en.wikipedia.org/wiki/9-slice_scaling)

La idea de este método es preservar los corners de una imágen y escalar el resto de las zonas.
Los Sprites tienen que ser configurados para poder usar el image type sliced, y esto lo
hacemos desde el sprite editor. Moviendo las reglas verdes que tenemos sobre la imagen,
dividiendo la imagen (como se puede ver) en 9 pedazos.
En el siguiente video podemos ver un ejemplo de como configurar correctamente una imagen
para que funcione con este método: https://www.youtube.com/watch?v=ga9iZ-BMgjY

Este método es fundamental no solo para ahorrar tamaño de memoria y disco al momento de
crear los paneles de IU, sino que podemos reutilizar un mismo prefab en diferentes ventanas
distintas.

Algunas características que necesita tener las imágenes para que este método funcione:

1. Los bordes definidos


2. Los bloques que se van a repetir tienen que poder hacerlo sin distorsionar (es decir
tener patrones repetitivos o colores sólidos).

Text Field - Text Size.

Un último punto a tener en


cuenta para que nuestra
interfaz quede bien y se
pueda escalar donde
corresponde son los campos
de texto.

Podemos haber configurado


el canvas y las imágenes
para que se adapten a las
distintas resoluciones, sin
embargo al momento de
hacer el build todo se ve
perfecto a excepción de los
textos. Esto se debe a que
por defecto Unity, no prepara
los textos para múltiples
resoluciones.

Para corregir esto es tan simple como tildar la opción “Best Fit” en la caja de texto. Al hacerlo
se nos habilitarán 2 opciones. Min size y Max Size. Estos serán (como su nombre lo indica)
El tamaño mínimo y máximo que tendrá nuestra fuente. De esta forma el texto tratará de entrar
de la mejor manera posible dentro de nuestra caja de texto manteniendo como boundaries esos
valores de tamaño.
Consideraciones:
1. - Max / Min Size sobreescribe el valor de Font Size. No importa el valor que tenga Font
Size, una vez seleccionamos Best Fit y completamos esos valores, el valor de Font Size
no se utiliza más.
2. El valor de Min Size y Max Size dependen de la fuente. Todas las fuentes tienen un
límite mínimo y máximo de tamaño. Un valor de min size, menor que el tamaño menor
que soporta la fuente nos va a devolver el tamaño mínimo de la misma, al igual que un
tamaño máximo mayor que el de la fuente, nos devolverá el tamaño máximo de la
misma.

Anchors
Los puntos de anclaje de nuestros elementos, no influyen demasiado en nuestra UI
auto-escalable a excepción de todos los que se encuentran en la fila y columna de Stretch.

Cualquiera de estos puntos de anclaje, se van a


asegurar que nuestros componentes mantengan
una relación horizontal o vertical con la pantalla,
independiente del tamaño y resolución de la
misma.
Por ejemplo, si queremos situar una barra de
vida que tenga siempre una proporción de 200px
respecto a cada margen horizontal (es decir,
200px a la izquierda y 200px a la derecha de
aire), entonces debemos seleccionar cualquiera
de los 3 anchor que aparecen en la columna de
stretch, en el medio (dependiendo la altura de
nuestra barra, top, middle o bottom).

De la misma forma la opción que se encuentra a


la derecha abajo, va a estirar nuestro
componente para ocupar todo el ancho y alto de
la pantalla, sin importar el cambio de tamaño o
resolución.
Correcto Manejo de Canvas/Paneles

Canvas
Estamos acostumbrados a armar toda una UI dentro de un Canvas. Independiente del uso del
Canvas, dejamos todos los elementos ahí y todo funciona perfecto.

Y esto está bien hacerlo, mientras nuestra app funcione bien y no tenga problemas de
performance. Sin embargo, si nuestra aplicación tiene una fuerte carga de UI (estamos
hablando de muchas ventanas y paneles al mismo tiempo), entonces muy probablemente nos
convenga dividir nuestros elementos de UI en distintas canvas.

Esto se debe a que al momento que renderiza el UI unity crea una malla para poder
representar cada uno de los elementos que hay en el canvas. Cuando hay un cambio en el
canvas este se marca como sucio y se informa al sistema que se tiene que recalcular y
redibujar.

Otra cosa a tener en cuenta es que los elementos del canvas son los últimos en dibujarse, así
que a pesar de que nuestro canvas esté configurado como World Space y haya otros
elementos en la escena que lo tapen, los píxeles correspondientes al canvas se calcularán
igualmente.

Esto ya nos da 2 flags que tenemos que tener en cuenta y prestar atención si nuestra UI
empieza a causar problemas de performance. Un repintado de todo el canvas puede consumir
muchos frames, en caso de tener muchos elementos y puede hacerlo con una acción tan
simple como un timer o incluso un hover de un botón.

El segundo, el canvas no respeta la occlusion culling, es decir que va a tratar de pintarse por
más que esté oculto, consumiendo tiempo de procesamiento por más que no lo podamos ver.

Entonces una buena práctica es dividir el UI en diversos canvas, la idea sería agrupar en un
mismo canvas los elementos que sean más susceptibles de actualizarse al mismo tiempo,
como podría ser la energía del ataque que va bajando cada vez que golpeamos y los puntos de
experiencia que vamos ganando por eliminar enemigos. Un punto interesante a tener en
cuenta, es que podemos crear un canvas dentro de otro canvas. Si el canvas hijo se ve
modificado no afectará a todo el canvas padre, ya que cada canvas está aislado, así que
simplemente se debería volver a calcular los elementos del canvas hijo, pero en ningún caso
los del padre.
Otro punto a tener en cuenta son los elementos interactivos de nuestro canvas. Los elementos
de UI que creamos en Unity tienen la propiedad Raycast Target esta propiedad hace que los
elementos del canvas sean susceptibles de ser clicados o tocados, es decir que puedan recibir
un input. Esto se traduce en que cada vez que nosotros hacemos click o touch sobre la pantalla
Unity revisa si hay algún elemento del UI que tenga marcada esta propiedad y que quede en la
línea de proyección de esa interacción con la pantalla. Si todos los elementos de nuestro
canvas tiene la propiedad de raycast activada estaremos haciendo que Unity realice más
cálculos de los necesarios.

El uso de las cámaras en los canvas definidos con un Render Mode de Screen Space o
World Space, también es importante. Si en estos dos modos no le especificamos qué cámara
vamos a usar Unity por defecto irá a buscar la main Camera de nuestra escena. Pero para
realizar esta búsqueda de manera automática se verá obligado a realizar una búsqueda
mediante el método Find, es decir, deberá pasar por todos los objetos de nuestra escena hasta
dar con el que responda a la Main Camera.

Paneles
Para utilizar contenedores con fondo tenemos 2 opciones en Unity, la primera es usar imágenes
y la otra es usar paneles. No hay una diferencia a nivel performance entre usar una u otra, sino
más bien conceptual.

Un panel es una imagen de Unity que tiene la propiedad Image Type, seteado como Slice por
defecto, por lo tanto implícitamente Unity nos recomienda utilizar paneles para que sean los
background o contenedores de nuestros “paneles” en el juego. Sin embargo, salvo esa
diferencia no hay nada que impida utilizar uno u el otro.

Horizontal,Grid,Vertical Layout
Estos componentes nos permiten de forma super rápida alinear elementos en la UI bajo cierto
criterio y asegurarnos que no solo se van a ver correctamente, sino que el agregar nuevos
elementos no va a romper la UI sino, por el contrario, va a tratar de reorganizar los elementos
de la mejor forma posible.
Para agregar los layout, simplemente elegimos cualquier componente de UI y le agregamos el
componente correspondiente.

Horizontal Layout
Como su nombre lo indica, va a ubicar los elementos de UI alineados de forma horizontal.

Entre las propiedades más comunes, tenemos la alineación de los hijos (Child Alignment), en
donde podemos elegir cómo va a ubicar los hijos dentro del panel (más allá de, “de forma
horizontal”) y las propiedades de padding, que básicamente nos determina qué espacio va a
tener el panel (interiormente) en sus bordes respecto a los hijos.

Vertical Layout
Es exactamente igual que el anterior, con las mismas opciones, pero en este caso los
elementos se alinean de forma vertical.
Grid Layout
Este componente si es distinto al resto ya que como primer parámetro nos pide el tamaño de
nuestras “celdas” en ancho y alto.

Esto quiere decir que la grilla que va a formar, va a tener N cantidad de elementos que
respeten ese ancho y alto. Los hijos de la grilla van a verse obligados a respetar ese tamaño,
incluso perdiendo sus proporciones, por lo tanto es importante setear correctamente este valor.

Scroll View
Un componente que es fácil de usar, pero que suele traer un poco de dolores de cabeza al
principio, es el Scroll View.

Crear un scrollview, es simple.

Sin embargo existen ciertos ajustes que debemos realizar para que nuestro scroll view funcione
correctamente.

¿Dónde ubicar el contenido?


El contenido de nuestro scrollview tiene que ser hijo del gameobject
Todos los elementos que pongamos ahí pasarán a ser parte de nuestra vista, sin embargo tirar
elementos sin ningún criterio no va a dar los resultados esperados.

Por eso una buena práctica es, primero que nada, definir cómo va a ser nuestro componente
(scroll vertical, scroll horizontal), por lo tanto podemos comenzar agregando a nuestro game
object “Content” un layout group acorde, por ejemplo la lista más común son una serie de
elementos uno abajo de otro de forma vertical, por lo tanto nuestro Content tendrá un Vertical
Layout Group agregado como componente.

De esta forma todos los elementos que agreguemos se irán ubicando


de forma vertical, uno bajo el otro.

Ahora bien, si nosotros le damos play y probamos el componente,


veremos que el scroll no se realiza de forma correcta, es decir
podemos scrollear pero el contenido se nos vuelve inmediatamente al
top.

Esto se debe a que nuestro “Content” no creció en tamaño, por mas


que le agregamos muchos elementos dentro.

Podemos ver en la imagen, la zona roja que pertenece al Gameobject


de Content.

Por tal motivo es que nuestro scroll no funciona.


La forma más fácil de solucionar este dilema es agregando un segundo componente al
gameobject de Content.
Content Size Fitter.

Este componente nos permite modificar el tamaño de un Rect Transform en ancho y alto, de
acuerdo al contenido o algún otro valor que nosotros deseemos incluir.

Cambiar de Unconstrained a Min Size o Preferred Size, termina de completar el funcionamiento


que queremos para nuestro Scroll View.

Content Size Fitter, es uno de los componentes que nos ayudan a que nuestra UI se ajuste de
acuerdo al contenido (en lugar de ajustar el contenido a la UI).
https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/HOWTO-UIFitContentSize.html

Máscaras
Al momento de trabajar con IU, podemos asignar máscaras a los componentes de UI para
ocultar elementos que se encuentren fuera de la máscara.

Por ejemplo, el mismo componente de Scrollview tiene una máscara en el GameObject del
ViewPort. Esta máscara asegura que los elementos de la lista que están por fuera del viewport
no sean visibles.

Sin embargo y en base a lo que estuvimos hablando con respecto a las propiedades del canvas
y la posibilidad de incluir elementos 3D o 2D que no formen parte de la UI dentro de nuestra UI,
podemos utilizar el Sprite Mask componente, en conjunto con la UI para ocultar partes de
nuestro modelo o personaje 2D en la UI.

Un simple ejemplo del uso de las máscaras puede verse acá:


https://www.youtube.com/watch?v=4pl8DcsCQ_k

Es importante destacar que, el componente Mask:

solo va a afectar a nuestros objetos de IU, siempre y cuando los objetos de UI se encuentren
debajo del gameobject que contiene la máscara y las partes visibles van a ser las que
determinen la imagen a usar de máscara.

También podría gustarte