Flujos de control y estructuras de decisión en Blueprints

Capítulo 5

Tiempo estimado de lectura: 8 minutos

+ Ejercicio

Por qué los flujos de control importan en tu grafo

En Blueprints, el “flujo de control” es la forma en que decides qué camino de ejecución sigue tu lógica. Dominarlo te permite: evitar condiciones duplicadas, controlar cuándo se ejecuta algo (y cuántas veces), recorrer colecciones de forma segura y mantener el grafo legible. En este capítulo verás nodos clave (Branch, Switch, DoOnce, Gate, Sequence, bucles) y patrones prácticos para construir lógica robusta sin caer en “spaghetti”.

Branch: decisiones binarias (Sí/No) sin complicaciones

Branch evalúa un booleano y ejecuta True o False. Úsalo cuando la decisión sea realmente binaria. Si empiezas a encadenar muchos Branch, suele ser señal de que necesitas un Switch (por estados) o una función que encapsule la condición.

Ejemplo típico: validar interacción

  • Condición: “¿El jugador está lo suficientemente cerca?”
  • Condición: “¿El objeto está bloqueado?”

En lugar de encadenar Branch en línea, es más legible crear una función booleana CanInteract() que devuelva un único booleano y usar un solo Branch en el evento de interacción.

Input Interact -> Branch (CanInteract? ) -> True: DoInteract / False: PlayDeniedFeedback

Switch: decisiones con múltiples caminos

Cuando tienes más de dos opciones, Switch reduce ramas y mejora la lectura. Los más comunes son Switch on Int, Switch on Name y, especialmente útil para gameplay, Switch on Enum.

Patrón de estado con Enums: Idle / Interact / Locked

Un patrón muy limpio para lógica de interacción es modelar el “estado” con un Enum. Por ejemplo: EInteractState con valores Idle, Interact, Locked. Luego, en el punto de decisión, usas Switch on EInteractState.

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

Guía práctica paso a paso: estado de interacción con Switch on Enum

  1. Crea un Enum (por ejemplo EInteractState) con: Idle, Interact, Locked.

  2. En tu Blueprint del objeto interactuable, crea una variable InteractState de tipo EInteractState. Define un valor inicial (por ejemplo Idle).

  3. En el evento de interacción (por ejemplo, cuando recibes la orden de interactuar), conecta a Switch on EInteractState.

  4. Implementa cada pin:

    • Idle: muestra prompt o prepara interacción (por ejemplo, cambiar a Interact).
    • Interact: ejecuta la acción (abrir, recoger, activar) y luego vuelve a Idle o pasa a Locked según el diseño.
    • Locked: reproduce feedback de “bloqueado” (sonido, UI, etc.).
  5. Opcional: encapsula el cambio de estado en una función SetInteractState(NewState) para centralizar efectos secundarios (por ejemplo, actualizar material, UI, colisión).

Ventaja: el grafo se lee como un diagrama de estados. Si mañana agregas Cooldown o Disabled, solo amplías el Enum y el Switch.

Sequence: ejecutar pasos en orden sin ramificar

Sequence dispara varias salidas en orden (Then 0, Then 1, etc.). Es útil cuando quieres “pasos” claros sin anidar cables.

Uso recomendado

  • Separar “validación”, “ejecución” y “feedback” en pasos.
  • Evitar que un solo cable se convierta en una autopista con muchas derivaciones.
OnInteract -> Sequence -> Then0: Validate -> Then1: Execute -> Then2: UpdateUI

Si cada paso crece, conviértelo en función (o macro si necesitas pines de ejecución múltiples).

DoOnce: limitar ejecuciones (con Reset)

DoOnce permite que un flujo pase solo la primera vez; luego bloquea hasta que reciba Reset. Es ideal para evitar spam de interacciones, disparos repetidos de efectos o inicializaciones accidentales.

Ejercicio 1: limitar una interacción con DoOnce + Reset

Objetivo: permitir que un botón se active una sola vez, pero que se pueda rearmar tras cierto evento (por ejemplo, al salir del área o tras un temporizador).

  1. En el evento de interacción, conecta a DoOnce.

  2. En la salida Completed, ejecuta la acción (por ejemplo, abrir una puerta o activar una luz).

  3. Define cuándo se rearma:

    • Opción A: al salir del trigger (evento de fin de solapamiento) llama a Reset.
    • Opción B: tras un Delay (por ejemplo 2s) llama a Reset.
    • Opción C: cuando el sistema termine (por ejemplo, puerta vuelve a cerrarse) llama a Reset.
OnInteract -> DoOnce -> Completed: ActivateButton -> Delay(2.0) -> Reset(DoOnce)

Consejo: si el “rearmado” depende de reglas complejas, crea una función RearmInteraction() y llama a Reset desde ahí.

Gate: abrir/cerrar el paso de ejecución

Gate funciona como una compuerta: si está abierta, deja pasar la ejecución; si está cerrada, la bloquea. Tiene entradas típicas: Open, Close, Toggle y Enter. Es excelente para controlar acceso a una acción según condiciones externas, sin recalcularlas cada vez con Branch.

Ejercicio 2: controlar acceso con Gate

Objetivo: permitir interacción solo mientras el jugador está dentro de un área, y bloquearla al salir.

  1. Coloca un volumen/trigger asociado al objeto.

  2. En el evento de inicio de solapamiento (cuando el jugador entra), conecta a Open del Gate.

  3. En el evento de fin de solapamiento (cuando el jugador sale), conecta a Close.

  4. Conecta el evento de interacción a Enter del Gate.

  5. En la salida del Gate, ejecuta la acción.

OnBeginOverlap(Player) -> Gate.Open
OnEndOverlap(Player) -> Gate.Close
OnInteract -> Gate.Enter -> DoInteract

Variación útil: usa Toggle para habilitar/deshabilitar interacción con un interruptor global (por ejemplo, “modo hackeo”).

Bucles: For, ForEach y While (con precaución)

Los bucles te permiten repetir lógica. En Blueprints, es crucial evitar bucles que puedan ejecutarse “sin fin” en un solo frame, porque pueden congelar el juego/editor. En general, prefiere ForEach para colecciones y usa While solo si estás completamente seguro de que terminará rápido y siempre.

For Loop

ForLoop itera desde un índice inicial a uno final. Útil para generar o procesar por índice (por ejemplo, 0..N-1). Si necesitas romper antes de tiempo, usa ForLoopWithBreak.

ForEach Loop

ForEachLoop recorre un array y te da el elemento actual y su índice. Es el patrón más común para procesar colecciones de actores, componentes, ítems de inventario, etc.

Ejercicio 3: procesar una colección con ForEach

Objetivo: al activar un panel, encender varias luces (array) y contar cuántas se encendieron.

  1. Crea una variable array Lights (por ejemplo, referencias a actores de luz o componentes).

  2. En el evento de activación, inicializa un contador TurnedOnCount a 0.

  3. Ejecuta ForEachLoop sobre Lights.

  4. En Loop Body:

    • Valida el elemento (si puede ser nulo) con IsValid.
    • Enciende la luz.
    • Incrementa TurnedOnCount.
  5. En Completed, muestra/usa el contador (por ejemplo, actualizar UI o desbloquear algo si el total supera un umbral).

ActivatePanel -> Set TurnedOnCount=0 -> ForEach(Lights)
LoopBody: IsValid? -> True: TurnOnLight -> TurnedOnCount++
Completed: CheckIfAllOn(TurnedOnCount)

Consejo: si el cuerpo del bucle crece, muévelo a una función ProcessLight(LightRef) para mantener el grafo legible.

While Loop (usar con precaución)

WhileLoop repite mientras una condición sea verdadera. El riesgo es que, si la condición nunca cambia a falso, el juego se quedará bloqueado. En Blueprints, muchas tareas “repetitivas en el tiempo” se resuelven mejor con temporizadores o lógica por ticks controlados, en lugar de While.

NecesidadMejor opciónEvitar
Reintentar algo a lo largo del tiempoTimer / eventosWhile en un solo frame
Procesar un arrayForEachWhile manual con índice
Buscar hasta encontrarForLoopWithBreakWhile sin límite

Si aun así usas While, añade un “límite de seguridad” (contador máximo) para garantizar salida.

Macros útiles para mantener el grafo limpio

Las macros son ideales para empaquetar patrones repetidos de flujo de control, especialmente cuando necesitas múltiples pines de ejecución o quieres reutilizar “mini-estructuras” en varios lugares. Úsalas para reducir cables y mejorar la lectura, pero evita meter demasiada lógica de negocio dentro: una macro debería ser pequeña y predecible.

Macro: Guard Clause (salida temprana)

Patrón: si no se cumple una condición, sal inmediatamente. Esto evita anidar Branch dentro de Branch.

Exec -> Branch(Condition) -> False: Return/Stop | True: Continue

En macro, puedes exponer: Exec In, Condition, Exec Out y opcionalmente Exec Failed para feedback.

Macro: Validate + Execute

Patrón: validar referencias y estado antes de ejecutar. Útil cuando repites IsValid + checks en muchos sitios.

Lectura del grafo: cómo evitar “spaghetti”

Reglas prácticas de diseño

  • Responsabilidad única por bloque: un bloque del grafo debería hacer una cosa (validar, ejecutar, actualizar UI), no todo a la vez.

  • Divide en funciones cuando la lógica produce un resultado (por ejemplo, CanInteract(), GetCurrentState(), ComputeScore()).

  • Usa macros cuando el valor está en el flujo (por ejemplo, guard clauses, secuencias repetidas, compuertas).

  • Evita cables largos: reordena nodos, usa Reroute y agrupa por secciones.

  • Nombra claramente: variables como InteractState, bHasKey, RemainingUses hacen que el Branch se lea solo.

Ejemplo de refactor: de Branch encadenados a Switch por estado

Si tu interacción tiene varios “modos” (bloqueado, en uso, listo, en cooldown), un árbol de Branch se vuelve difícil de mantener. Cambia a:

  • Un Enum de estado.
  • Un Switch on Enum como punto central.
  • Funciones pequeñas por caso: HandleIdle(), HandleInteract(), HandleLocked().
OnInteract -> Switch(InteractState) -> Idle: HandleIdle() | Interact: HandleInteract() | Locked: HandleLocked()

Ahora responde el ejercicio sobre el contenido:

En un Blueprint, ¿qué enfoque mejora la legibilidad y escalabilidad cuando una interacción puede estar en varios estados (por ejemplo, Idle, Interact, Locked) en lugar de encadenar muchos Branch?

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

¡Tú error! Inténtalo de nuevo.

Cuando hay más de dos caminos, un Switch (especialmente Switch on Enum) reduce ramas, se lee como un diagrama de estados y facilita agregar nuevos estados sin convertir el grafo en "spaghetti".

Siguiente capítulo

Interacción del jugador y entrada de controles en Unreal Engine

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

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.