Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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:
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).
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
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.
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.
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:
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.
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.
Sin embargo existen ciertos ajustes que debemos realizar para que nuestro scroll view funcione
correctamente.
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.
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.
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.
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.