Interfaces de usuario con UMG y conexión con gameplay

Capítulo 9

Tiempo estimado de lectura: 8 minutos

+ Ejercicio

Qué es UMG y cómo se relaciona con el gameplay

UMG (Unreal Motion Graphics) es el sistema de Unreal Engine para crear interfaces de usuario mediante Widgets. Un Widget es un Blueprint (Widget Blueprint) que define una jerarquía visual (paneles, textos, imágenes, barras) y una lógica asociada (funciones, eventos, animaciones). En gameplay, el objetivo es que el UI refleje el estado del juego (salud, inventario, interacción) de forma correcta y eficiente.

Hay dos formas comunes de “conectar” datos del juego al UI:

  • Bindings (funciones que se evalúan para devolver un valor al UI). Son cómodos, pero pueden ejecutarse con frecuencia y afectar rendimiento si se abusa.
  • Actualización por evento (recomendado): el gameplay emite cambios (por ejemplo, “salud cambió”) y el widget actualiza solo cuando hace falta.

Creación de Widgets en UMG: estructura y jerarquía de paneles

Widget Blueprint: Designer vs Graph

En un Widget Blueprint trabajarás principalmente en dos pestañas:

  • Designer: construyes la interfaz arrastrando controles (Text, Progress Bar, Image) y organizándolos en paneles (Canvas Panel, Vertical Box, Horizontal Box, Overlay, etc.).
  • Graph: defines la lógica: inicialización, funciones para actualizar textos/barras, y eventos personalizados.

Paneles típicos y cuándo usarlos

  • Canvas Panel: útil para posicionamiento libre (anclas, offsets). Ideal para un HUD.
  • Overlay: apila elementos uno encima de otro (por ejemplo, un fondo y encima el texto).
  • Vertical Box / Horizontal Box: distribución automática en columna/fila (contadores, listas).
  • Size Box: fuerza tamaño fijo o mínimo/máximo (útil para barras).

Controles básicos del capítulo

  • Text: para contador de objetos y mensajes contextuales.
  • Progress Bar: para salud (Percent entre 0 y 1).
  • Border / Image (opcional): para mejorar legibilidad del HUD.

Práctica guiada: HUD con barra de salud, contador y mensaje de interacción

Vas a construir un HUD que muestre: (1) barra de salud, (2) contador de objetos recogidos, (3) mensaje contextual “Pulsa E para interactuar” que aparece solo cuando corresponde.

Paso 1: Crear el Widget Blueprint del HUD

1) En el Content Browser: Add > User Interface > Widget Blueprint. Nómbralo WBP_HUD.

Continúa en nuestra aplicación.
  • Escuche el audio con la pantalla apagada.
  • Obtenga un certificado al finalizar.
  • ¡Más de 5000 cursos para que explores!
O continúa leyendo más abajo...
Download App

Descargar la aplicación

2) Abre WBP_HUD en Designer. Asegúrate de tener un Canvas Panel como raíz.

3) Barra de salud:

  • Arrastra un Progress Bar al Canvas.
  • En Anchors, ancla arriba-izquierda (o donde prefieras).
  • Ajusta tamaño (por ejemplo 300x20) y posición.
  • En el panel Details, marca Is Variable para poder referenciarla desde el Graph. Renómbrala a PB_Health.

4) Contador de objetos:

  • Arrastra un Text al Canvas.
  • Colócalo cerca de la barra o en otra esquina.
  • Marca Is Variable y renómbralo a TXT_Items.
  • Texto inicial sugerido: Items: 0.

5) Mensaje contextual de interacción:

  • Arrastra un Text al Canvas, céntralo abajo o cerca del retículo.
  • Marca Is Variable y renómbralo a TXT_Interact.
  • Texto sugerido: Pulsa E para interactuar.
  • En Details > Visibility, ponlo inicialmente en Hidden (o Collapsed si quieres que no ocupe espacio en layouts).

Paso 2: Definir una API del widget (funciones/eventos para actualizar)

En el Graph de WBP_HUD, crea funciones simples para actualizar el UI por evento. Esto evita bindings costosos.

Función 1: SetHealthPercent

  • Crea una función llamada SetHealthPercent.
  • Input: HealthPercent (Float).
  • En el cuerpo: PB_Health > Set Percent con HealthPercent.

Función 2: SetItemCount

  • Crea una función SetItemCount.
  • Input: Count (Integer).
  • Construye el texto: por ejemplo con Format Text usando Items: {0} y conectando Count.
  • Luego TXT_Items > SetText.

Función 3: SetInteractPromptVisible

  • Crea una función SetInteractPromptVisible.
  • Inputs: bVisible (Boolean) y opcional Message (Text) si quieres variar el mensaje.
  • Si incluyes Message, primero TXT_Interact > SetText.
  • Luego TXT_Interact > SetVisibility a Visible si bVisible es true, si no a Hidden o Collapsed.

Paso 3: Instanciar el widget y añadirlo al Viewport

El HUD normalmente se crea al inicio para el jugador local. Dos ubicaciones comunes: Player Controller o Character. En proyectos con UI, el Player Controller suele ser un buen lugar por responsabilidad (gestiona input/UI), pero también es válido desde el Character si tu arquitectura es simple.

Opción recomendada: desde el Player Controller

  • En tu Blueprint de Player Controller (por ejemplo BP_PlayerController), crea una variable: HUDWidget de tipo WBP_HUD (Object Reference).
  • En Event BeginPlay:
Create Widget (Class = WBP_HUD, Owning Player = Self) -> Promote to variable HUDWidget -> Add to Viewport

Notas importantes:

  • Conecta Owning Player al Player Controller para que el widget tenga contexto del jugador local.
  • Guarda la referencia en HUDWidget para poder actualizarlo luego sin buscarlo.

Gestión de visibilidad del HUD completo

  • Para ocultar/mostrar todo el HUD: HUDWidget > Set Visibility (Visible/Hidden/Collapsed).
  • Si vas a alternar menús, también puedes usar Remove from Parent para destruirlo visualmente, pero entonces deberás recrearlo o conservar referencia y reañadirlo.

Paso 4: Mantener referencias seguras y evitar errores comunes

Para actualizar el UI desde gameplay necesitas una referencia válida al widget. Reglas prácticas:

  • Guarda la referencia al crear el widget (variable HUDWidget).
  • Valida antes de usar: usa Is Valid sobre HUDWidget antes de llamar funciones (especialmente si el widget puede ser removido).
  • No uses Get All Widgets Of Class para actualizar cada vez: es más lento y propenso a errores.
  • Si el widget se crea en el Player Controller, otros Blueprints pueden acceder a él obteniendo el Controller y casteando (o mejor, exponiendo una función en el Controller que actualice el HUD).

Conectar datos del juego al UI: bindings vs eventos (rendimiento)

Bindings controlados (cuándo usarlos)

Un binding típico es enlazar el Percent de la Progress Bar a una función GetHealthPercent() en el widget. Ventajas: rapidez de implementación. Desventajas: puede evaluarse repetidamente y escalar mal si tienes muchos elementos.

Si decides usar bindings, mantenlos simples (sin casts repetidos, sin búsquedas globales). Una estrategia “controlada” es cachear referencias en Event Construct del widget (por ejemplo, guardar referencia al Character) y que el binding solo lea variables ya disponibles.

Actualización por evento (recomendado)

La idea es: cuando cambie la salud, el gameplay llama a HUDWidget.SetHealthPercent. Cuando recojas un objeto, llama a HUDWidget.SetItemCount. Cuando entres/salgas de un área interactuable, llama a HUDWidget.SetInteractPromptVisible.

Esto reduce trabajo por frame y hace más predecible el rendimiento.

Implementación práctica de eventos: salud, objetos e interacción

1) Salud: actualizar la barra cuando cambie

Supón que tu personaje tiene variables CurrentHealth y MaxHealth. Cada vez que recibas daño o curación:

  • Calcula HealthPercent = CurrentHealth / MaxHealth (Float).
  • Obtén el Player Controller (si el HUD vive allí) y llama a una función que actualice el HUD.

Patrón recomendado: crear en el Player Controller una función UpdateHealthUI(Current, Max) que internamente haga:

IsValid(HUDWidget) -> HUDWidget.SetHealthPercent(Current / Max)

Así el Character no necesita conocer detalles del widget, solo “pide” al Controller que actualice UI.

2) Contador de objetos: actualizar al recoger

Cuando el jugador recoja un objeto (por ejemplo, en el evento de interacción o al solapar con un pickup):

  • Incrementa tu variable ItemsCollected.
  • Llama a HUDWidget.SetItemCount(ItemsCollected) (idealmente a través del Player Controller).

Si tu contador depende de un sistema de inventario, la idea es la misma: el evento “añadido al inventario” dispara la actualización del texto.

3) Mensaje contextual: mostrar/ocultar según posibilidad de interactuar

El mensaje contextual debe aparecer solo cuando el jugador esté cerca de algo interactuable y tenga sentido mostrarlo.

  • Cuando detectes que el jugador puede interactuar (por ejemplo, al entrar en un trigger del objeto interactuable): llama SetInteractPromptVisible(true, "Pulsa E para interactuar").
  • Cuando deje de poder interactuar (salir del trigger o perder foco): llama SetInteractPromptVisible(false).

Recomendación: si tienes distintos tipos de interacción, pasa un Message variable (por ejemplo: “Abrir”, “Recoger”, “Hablar”) para reutilizar el mismo widget.

Gestión de visibilidad y estados del UI

Hidden vs Collapsed

  • Hidden: no se ve, pero sigue ocupando espacio en layouts (útil si quieres mantener el hueco).
  • Collapsed: no se ve y no ocupa espacio (útil en listas o cajas).

Para el mensaje contextual en un Canvas, cualquiera funciona; para layouts automáticos (Vertical Box), Collapsed suele ser más limpio.

Mostrar/ocultar HUD completo (por ejemplo, al abrir un menú)

Si más adelante añades un menú, puedes ocultar el HUD sin destruirlo:

  • HUDWidget > Set Visibility = Hidden
  • Al cerrar el menú: Set Visibility = Visible

Esto mantiene referencias y evita recreación constante.

Checklist de depuración rápida

ProblemaCausa típicaSolución
No aparece el HUDNo se ejecutó Add to Viewport o se creó en el lugar equivocadoVerifica BeginPlay del Player Controller y que el Pawn use ese Controller
La barra no cambiaNo se llama a SetHealthPercent o el Percent no está entre 0 y 1Clampa el valor y confirma que el evento de daño/curación llama a la actualización
Acceso a None al actualizarReferencia del widget nula o removidaGuardar referencia al crear y usar Is Valid antes de llamar
UI lentoBindings complejos o demasiadosPasar a actualización por evento y cachear referencias

Ahora responde el ejercicio sobre el contenido:

¿Cuál es la práctica recomendada para mantener un HUD actualizado de forma eficiente y con menos impacto en el rendimiento?

¡Tienes razón! Felicitaciones, ahora pasa a la página siguiente.

¡Tú error! Inténtalo de nuevo.

La actualización por evento evita evaluaciones frecuentes como en bindings y reduce trabajo por frame. Guardar la referencia al crear el widget permite actualizarlo sin búsquedas costosas y validarlo antes de usarlo.

Siguiente capítulo

Depuración y calidad de Blueprints en Unreal Engine

Arrow Right Icon
Portada de libro electrónico gratuitaUnreal Engine para Principiantes: Fundamentos de Blueprints y Lógica de Gameplay
82%

Unreal Engine para Principiantes: Fundamentos de Blueprints y Lógica de Gameplay

Nuevo curso

11 páginas

Descarga la aplicación para obtener una certificación gratuita y escuchar cursos en segundo plano, incluso con la pantalla apagada.