Hola, sean bienvenidos a mi nuevo post. Hoy hablaremos sobre como crear controles de interfaces para nuestros juegos, es decir botones, barras de vida, puntajes, en fin todo aquello relacionado a mostrar los datos de nuestro personaje o las acciones disponibles para el mismo, como una aventura grafica por ejemplo, en la leccion de hoy veremos como se crean los mismos.

godot_editor_ui
Fuente: docs.godotengine.org

En este post aprenderemos los siguientes puntos:

  • Las cinco nodos de control mas utiles para la interfaz de nuestros juegos
  • Como manipular el delimitador (anchor) de los elementos de la interfaz del usuario
  • Como ubicar y organizar la interfaz del usuario con contenedores
  • Los cinco contenedores mas comunes.

Solo trabaja con Nodos de Control porque ellos solo tienen propiedades las cuales nos permiten trabajar con alguna otra, no uses nodos del tipo Sprite, Node2D, etc porque estos no funcionaran pero si puedes utilizar algunos como AnimationPlayer, Tween o StreamPlayer, los Nodos de Controls son CanvasItems, estos son muy parecidos al Nodo2D permitiendonos usar sombreadores sobre ellos. Si bien Godot contiene un monton de nodos para ser utilizados como controles, para los juegos hay cinco controles basicos:

  • Label: Para mostrar un texto.
  • TextureRect: Es utilizado para mostrar un color de fondo de pantalla o una imagen
  • TextureProgress: Para las barras de vida, de carga, etc
  • NinePatchRect: Para paneles escalables
  • TextureButtons: Para crear botones
five_most_common_nodesFuente: docs.godotengine.org

TextureRect

Este nodo tiene la propiedad de mostrar una textura o una imagen en la interfaz del usuario, es muy similar al nodo Sprite. Si seteas la propiedad del modo Stretch nos permitira cambiar su conducta:

  • Scale on Expand (compact): Escala la imagen para encajar en el delimitador del rectangulo del nodo, solo si es expand (es decir true) de lo contrario usa keep (mantener)
  • Scale: Escala la imagen para encajar en el delimitador del rectangulo del nodo
  • Tile: Repite la imagen pero no la escala
  • Keep: Fuerza a la imagen a mantener su tamaño original en el rincon superior izquierdo del Rectangulo
  • Keep Centered: Idem al punto anterior pero en el centro del rectangulo.
  • Keep Aspect: Escala la imagen pero fuerza a mantener el ratio del aspecto y lo ubica en el rincon izquierdo superior del rectangulo
  • Keep Aspect Centered: Idem al anterior pero lo ubica en el centro del rectangulo
  • Keep Aspect Covered: Idem al anterior pero la parte mas corta encaja con el delimitador del rectangulo y las otras con el limite del nodo

Como los nodos Sprites, se puede modular los color de este tambien, se utiliza la propiedad Modulate como se ve en la imagen inferior.

five_common_nodes_textureframe
Ejemplo de modular a color Rojo (Fuente: docs.godotengine.org)

TextureButton

Este nodo es muy similar al anterior pero con la diferencia que nos permite guardar hasta cinco texturas en diferentes slots, estas texturas corresponden a los estados del nodo en si:

  • Normal
  • Pressed (Apretado)
  • Hover (Flotante)
  • Disabled (Desactivado)
  • Focused (Enfocado)

De los estados antes comentados usualmente se utilizan los tres primeros, obviamente utilizaremos todos los estados en algunas circunstancias y el quinto estara mas utilizado cuando utilicemos teclado como interfaz. Despues tendremos un sexto slot, la mascara para el click, donde definiremos el area a utilizar para hacerla “clickeable”, esto es a traves de una textura de 2 bits en blanco y negro. En la base de este nodo, encontraras muy pocas opciones para cambiar la conducta del mismo.

  • Toggle mode en estado On, va a alternar entre Activo y Normal cuando es presionado
  • Disabled, lo desactiva por defecto y utiliza el cuarto slot antes mencionado
  • Modulate, igual al nodo anterior
  • Resize, cambia el tamaño del boton, idem al anterior Nodo
  • Rescale, cambia la escala del boton, idem al anterior Nodo
five_common_nodes_texturebutton
Ejemplo de slots de un TextureButton (Fuente: docs.godotengine.org)

TextureProgress

Este nodo utiliza capas para almacenar hasta tres sprites para crear la animacion del mismo, las texturas Under y Over hacen un efecto Sandwich sobre la del progreso, la cual muestra el valor de la barra. La propiedad Mode controla la forma de mostrar la barra, puede ser horizontal, vertical o radial. Si elegimos esta opcion debemos ingresar el Initial angle (angulo inicial) y Fill degrees (angulo del relleno) las cuales limitaran el rango de la barra. Para crear una animacion en la barra, debemos ir a la seccion de Range y setear el valor min (minimo) y max (maximo) por ejemplo si lo usaramos para representar una barra de vida se deberia setear el min en cero, y el max en el valor maximo de vida. Para variar el valor de la barra se utiliza el parametro update, supongamos esta situacion, creamos la barra dejamos los valores predeterminados, min igual a cero y max igual a 100, y si seteamos la propiedad update a 40, este nos dejara la barra al 40% y nos ocultara el 60% restante.

five_common_nodes_textureprogress
Fuente: docs.godotengine.org

Label

Este nodo sirve para escribir texto en pantalla, el texto se ingresa en la propiedad Text, si necesitamos respetar los margenes y que nuestro texto se ajuste al nodo, debemos tildar la opcion Autowrap para setearlo en On y tambien podemos ubicar el texto de forma horizontal (Align) y vertical (Valign)

five_common_nodes_label
Ejemplo de texto, y algunas propiedades (Fuente: docs.godotengine.org)

NinePatchRect

Este nodo toma una textura y la divide en tres filas y en tres columnas. El centro y los lados encajan cuando escalas la textura pero no escala las esquinas. Es muy util para construir paneles, cajas de dialogo y fondos escalables para la interfaz del usuario.

five_common_nodes_ninepatchrect
Fuente: docs.godotengine.org

Ahora hablaremos dos formas de trabajo para una interfaz de usuario mas sensible:

  • Se pueden tener muchos controladores a tu disposicion para escalar y colocar muchos elementos de la interfaz, todo esto a traves de sus childrens.
  • Por otro lado, tenes el menu de layout el cual nos ayuda a delimitar, ubicar y cambiar el tamaño de los elementos de la interfaz a a traves de sus padres (parents)

Estos dos metodos no son compatibles entre si todo el tiempo porque de la primera opcion el contenedor se encarga de administrar a todos sus hijos y por ende no puede ser utilizado el menu de layout. Esto nos puede traer un poco mas de trabajo porque vamos a necesitar varios de ellos para tener una interfaz funcional. En cambio con el layout, nosotros trabajamos con la parte superior de nuestro children, esto ocasiona el no poder agregar nuevos contenedores y va a ser mas dificil ordenarlos por filas, colunas o rejilla. Por como digo siempre, esto va a quedar a criterio del programador para cada situacion. Ahora veremos como ubicar los elementos de una interfaz a traves de los delimitadores (Anchors), como hemos visto en otros posts los nodos de control tienen las propiedades de position (posiscion), size (Tamaño), anchors (delimitador) y margins (margenes). Los anchors definen los puntos de origen de left (Izquierda), top (Arriba), right (Derecha) y bottom (abajo) si cambiamos cualquiera de estos puntos tambien cambiaremos los puntos de referencia de los margins.

anchor_property
Ejemplo de Anchor de un elemento (Fuente: docs.godotengine.org)

En la imagen superior vemos como se pueden modificar los anchors a traves de la solapa Inspector del elemento, este metodo no es la mejor opcion para modificar los propiedades. Para modificar lo ideal, es utilizar la opcion de Layout a traves de la toolbar

godot00
Ubicacion exacta de Layout (Disposicion en Español)
layout_menu
Fuente: docs.godotengine.org

Como pueden ver esta opcion es mucho mas practica para elegir la posicion del nodo control, esta funcion se activa solamente con este tipo de nodos. El valor de anchor es relativo al contenedor, cada anchor tiene un valor entre cero y uno, es decir cuando sea cero los valores anchor de top y left significara sin margen (margins) y tanto los bordes del nodo child como los del parent (es decir el contenedor) se alinearan entre si. Por lo tanto un uno para los anchors de right y bottom sera la alineacion entre los bordes del contenedor y del nodo child. Por otro lado, el margin representa la distancia al anchor position en pixeles, mientras los anchors son relativos al tamaño del contenedor parent (es decir el principal)

ui_anchor_and_margins
Fuente: docs.godotengine.org

Los margins cambian automaticamente con los anchors, estos cambian cuando se modifica el nodo control tanto de posicion como de tamaño. Ellos representan la distancia desde los bordes del nodo control hasta los delimitadores (anchors), la cual es relativa al contenedor, es por esto nuestros nodos control deben estar siempre en un contenedor. Veamos la siguiente imagen

control_node_margin
Fuente: docs.godotengine.org

Si no seteamos ningun contenedor seran relativos al rectangulo definido a la propiedad Rect de la solapa Inspector. Probemos con esto, modifique los anchors de un contenedor observe a los margins, estos cambiaran automaticamente, en ocasiones muy poco frecuentes, por no decir inusuales, debera modificarlo de forma manual. Veamos el siguiente ejemplo para explicarlo de forma mas grafica.

textureframe_in_box_container_fill
Fuente: docs.godotengine.org

Todo nodo de control, tiene sus flags (u opciones) de tamaño, esta le dice al contenedor como deben escalar los elementos de la interfaz, con la opcion Fill le diremos de utilizar el maximo espacio posible en el eje elegido pero respetando el tamaño de sus compañeros como vemos en la foto anterior. en cambio si utilizamos el flag Expand se expandera lo maximo disponible tanto definido por los delimitadores (anchors) o por sus compañeros como se ve en la siguiente imagen

textureframe_in_box_container_expand
Fuente: docs.godotengine.org

Otra virtud de los contenedores es tener la propiedad de ordenar automaticamente todos sus nodos, esto nos facilitara las tareas a la hora de agregar nuevos elementos de la interfaz del usuario. Si necesitamos modificar el orden de los nodos, dentro de la solapa Inspector bajen hasta Custom contacts. Ahora hablaremos de los cinco contenedores mas utiles:

  • MarginContainer, para agregar margins alrededor de la interfaz del usuario.
  • CenterContainer, para centrar a los childrens en la caja delimitadora.
  • VBoxContainer, ordena elementos de la interfaz del usuario en columnas.
  • HBoxContainer, idem al anterior pero en filas.
  • GridContainer, ordena los nodo control en un patron de tipo grilla.

CenterContainer

Es utilizado para tener en el centro todos los elementos convenientes, por ejemplo una pantalla de titulo, si es completamente necesario quedar centrado esta es tu mejor opcion.

five_containers_centercontainer
Fuente: docs.godotengine.org

MarginContainer

Este contenedor agrega un margin en todos nuestro nodos childs, esto es util englobar en todo el viewport una separacion entre los bordes de la ventana y la interfaz del usuario. Como se puede ver en la imagen siguiente.

five_containers_margincontainer
Ejemplo de como se separo automaticamente (fuente: docs.godotengine.org)

VBoxContainer y HBoxContainer

Hay dos tipo de BoxContainer, el VBoxContainer y el HBoxContainer, si nosotros utilizamos estos tipos implica no poder utilizar el BoxContainer como clase de ayuda. Estos contenedores son utilizados para ordenar los elementos en filas o columnas, tambien podemos crear una grilla especial con diferentes tamaños.

five_most_common_nodes
Ejemplos de un HBoxContainer con algunos elementos (Fuente: docs.godotengine.org)

Si utilizamos el VBoxContainer este los alineara en una columna y los separara en base a la propiedad Space, el HBoxContainer lo hace en forma de fila, agrega la propiedad add_spacer para definir mejores separadores a traves de script.

GridContainer

Este contenedor ordena los elementos en forma de grilla, lo unico que podremos controlar son las columnas, las filas las creara automaticamente, por ejemplo si nosotros tenemos nueve elementos, lo dividiremos en tres columnas y se generara automaticamente tres filas, y si ahora agregaramos tres elementos mas, se generaria una fila mas para contener los doce elementos. Como los contenedores anteriores tambien tiene dos propiedades para controlar la separacion horizontal y vertical.

five_containers_gridcontainer
Ejemplo de distribucion de elementos con GridContainer (Fuente: docs.godotengine.org)

Bueno hasta aqui hemos visto como crear interfaces de usuario a traves de nodo control, tambien hemos visto los containers, como ordenarlos pero en forma muy basica, en los proximos posts iremos adentrandonos cada vez mas para entender mejor el concepto de los nodo control para efectuar estas interfaces. Espero les haya sido util, nos vemos en el proximo post.