Hoy toca contenido exclusivo para el blog, algo que no vais a encontrar en ningún otro sitio. Vamos a crear un menú dinámico que ajusta su altura según el número de Labels que contenga, evitando que alguno quede fuera de su área.
En su día busqué tutoriales sobre esto, pero lo único que encontré fueron ejemplos de menús de inicio o menús estáticos que no se adaptaban al contenido.
Como va ser costumbre en las entradas donde haga mi propio código, seguro que hay mejores formas de hacerlo mejor y mas optima.
El menú que he creado es pequeño para encajar en mi proyecto en el que estoy trabajando. Para evitar problemas en este tutorial, ajustaremos el viewport a un tamaño reducido y forzaremos la resolución a 1920x1080, de forma que podamos verlo bien sin quedarnos ciegos en el proceso.
El PNG del fondo y el selector se puede descargar desde el GitHub.
https://github.com/ApuntesGodot/apuntesgodot.blogspot.com/tree/main/MenuDinamico
Vamos a crear la escena MenuDinamico(MarginContainer) con la siguiente estructura.
- MenuDinamico(MarginContainer)
- NinePatchRect
- VBoxContainer
- Label, Label1, Label2.
Fuente usada (https://fonts.google.com/specimen/Mozilla+Text)
- Selector (Sprite2D).
Es posible que las letras vean borrosas, para arreglar este problema, vamos hacerle doble click al fichero de la fuente.
Habilitamos Multichannel Signed Distance Field y pulsamos Reimport..
Y ahora vamos crear el script.
Vamos a revisar el código por partes.
Index_selected servirá para que internamente sepa el menu que elemento ese el seleccionado por el jugador.
Seleccionaremos todos los Label del VBoxContainer; cualquier otro tipo de nodo se ignorará.
Trucazo: si a los Label les adjuntas un script con class_name Etiqueta, podrás buscarlos por ese nombre y omitir los que no lo tengan.
Algo que he aprendido con este tutorial, ese que desde la función ready, ninguna instrucción de cambio de tamaño funciona si no le agregas un await get_tree().process_frame.
Desde _ready()
llamamos a dos funciones:
-
ajustar_tamaño_menu()
, que reduce al mínimo posible el VBoxContainer. Esto es útil si eliminamos opciones durante el juego, ya que al borrarlas podrían dejar un hueco en el menú y luego ajusta el tamaño del MarginContainer, añadiendo un margen extra en la parte inferior del menú.. -
opcion_seleccionada(), usando index_selected, sacamos su posición global y cambiamos la ubicación del Sprite2D Selector.
Desde aquí, gestionamos que el Selector solo pueda moverse por las opciones que tiene, evitando que index_selected y como hemos visto en opción_seleccionada, evitamos que index_selected llame a una posición de labels fuera del rango.
Cuando pulsemos Space/Enter, emitira la señal con el numero de posición seleccionada, esta señal la tendremos que conectar a la escena con la que queramos que tenga interacción.
Esto es una forma simplificada de comunicar el menú con otra escena y es muy mejorable, ya que hacer el menú se comunique enviando números es poco intuitivo.
Y hasta aquí hemos llegado. Reconozco que no soy el mejor explicando, pero hago lo que puedo, tengo que dejar las explicaciones para que mi yo del futuro con mas experiencia sepa porque lo hice de esta forma cuando había otras formas mejores de hacerlo.
El tema de las letras pequeñas borrosas lo solucione de este video.
No hay comentarios:
Publicar un comentario