Variables en Blueprints: tipos, organización y exposición
Una variable es un dato que tu Blueprint guarda y usa para tomar decisiones o modificar el comportamiento. Elegir el tipo correcto y exponerlo bien (para edición o para acceso desde otros Blueprints) reduce errores y hace tu proyecto más escalable.
Tipos de variables más usados (y cuándo elegirlos)
- Boolean (bool): estados binarios (abierto/cerrado, encendido/apagado).
- Integer (int): contadores, índices, cantidades discretas.
- Float: valores continuos (velocidad, tiempo, interpolaciones).
- Vector: posiciones, direcciones, escalas.
- Rotator: rotaciones (yaw/pitch/roll).
- String / Name: identificadores y texto.
Namesuele ser mejor para etiquetas y comparaciones. - Enum: estados con múltiples opciones (por ejemplo:
Closed,Opening,Open,Closing). - Object Reference: referencia a otro objeto/actor (por ejemplo, una puerta específica).
- Class Reference: referencia a una clase (para spawnear o filtrar tipos).
Crear variables con valores por defecto, categorías y tooltips
En el panel My Blueprint crea una variable y configura:
- Default Value: el valor inicial que tendrá el Blueprint (útil para prototipado y comportamiento estándar).
- Category: agrupa variables en el panel de detalles (por ejemplo:
Door,Switch,Debug). - Tooltip: describe qué hace y unidades (por ejemplo:
Velocidad de apertura en grados/segundo).
Convención práctica: usa nombres claros y consistentes, por ejemplo bIsOpen (bool), OpenSpeed (float), TargetDoor (Door reference).
Exponer variables: Instance Editable y Blueprint Read/Write
Hay dos necesidades comunes: editar valores desde el editor por instancia, y permitir que otros Blueprints lean/escriban el valor.
- Instance Editable: permite modificar la variable en el panel Details de cada instancia colocada en el nivel. Útil para ajustar
OpenSpeedpor puerta o asignar una referencia específica. - Blueprint Read Only / Read Write: controla si otros Blueprints pueden leer o modificar la variable cuando tienen una referencia a este actor. Útil para exponer estado (
bIsOpen) o permitir configuración desde fuera.
Recomendación: por defecto, mantén variables internas como privadas (no expuestas) y expón solo lo necesario. Si necesitas que otros Blueprints cambien algo, considera crear funciones (por ejemplo OpenDoor()) en lugar de permitir escritura directa.
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
Descargar la aplicación
Referencias: cómo obtener y guardar actores
Una referencia es “un puntero” a un actor u objeto existente. Sin referencia, no puedes llamar funciones ni leer variables del otro Blueprint. En gameplay, las referencias suelen obtenerse de tres formas: por eventos de colisión/overlap, por búsqueda (tag/clase), o asignándolas desde el editor.
1) Obtener referencias mediante colisión/overlap
Escenario típico: un interruptor detecta al jugador cuando entra en un área.
- Agrega un componente de colisión (por ejemplo
Box Collision) al actor. - Usa el evento
OnComponentBeginOverlap. - Del pin
Other Actorobtienes una referencia al actor que entró.
Buenas prácticas:
- Filtra por tipo antes de usar la referencia (por ejemplo, comprobar si es el jugador).
- Guarda la referencia en una variable solo si la necesitas después (por ejemplo
OverlappingActor).
2) Buscar actores por etiqueta (Actor Tags)
Útil cuando quieres encontrar actores en el nivel sin asignarlos manualmente, pero sin depender de un nombre específico.
- En el actor objetivo (por ejemplo la puerta), añade una etiqueta en Details > Actor > Tags, por ejemplo
Door_A. - En el Blueprint que busca, usa
Get All Actors with Tag. - Selecciona el primer elemento del array (si esperas uno) y guárdalo en una variable de referencia.
Precaución: Get All Actors... puede ser costoso si lo llamas frecuentemente. Úsalo en inicialización (por ejemplo al comenzar) o cuando sea necesario, no cada frame.
3) Asignación desde el editor (la forma más limpia para niveles diseñados a mano)
Cuando el diseñador coloca un interruptor y una puerta concretos, lo más robusto es exponer una variable de referencia y asignarla en el editor.
- Crea una variable
TargetDoordel tipo BP_Door Object Reference (o mejor, una interfaz; lo veremos más abajo). - Activa Instance Editable (y opcionalmente Expose on Spawn si se crea por spawn).
- En el nivel, selecciona el interruptor y en Details asigna la puerta arrastrándola desde el World Outliner.
Ventaja: evita búsquedas, es explícito y fácil de depurar.
Comunicación entre Blueprints
Una vez que tienes una referencia, necesitas un mecanismo para comunicar intención: “abre”, “cierra”, “cambia velocidad”, “notifica evento”. Hay tres herramientas clave: casting, interfaces y dispatchers.
Casting básico (rápido, pero crea dependencia)
Cast To BP_Door intenta tratar una referencia genérica (por ejemplo Other Actor) como un tipo específico. Si el objeto realmente es de ese tipo, el cast tiene éxito y puedes acceder a sus funciones/variables.
Ejemplo típico: en un overlap, haces cast del Other Actor a BP_Player para confirmar que es el jugador.
- Pros: simple y directo.
- Contras: dependencia fuerte (el Blueprint “conoce” el tipo exacto). Si cambias la clase, debes actualizar casts.
Blueprint Interfaces (comunicación sin dependencia fuerte)
Una Blueprint Interface define un “contrato” de funciones que cualquier Blueprint puede implementar. El emisor no necesita saber la clase exacta del receptor; solo necesita que implemente la interfaz.
Cuándo usarla: cuando varios tipos de actores podrían responder a la misma acción (puertas, luces, plataformas) o cuando quieres desacoplar interruptores de puertas específicas.
Crear e implementar una interfaz
- Crea una interfaz:
BPI_Interactableo específica:BPI_DoorControl. - Define una función, por ejemplo
SetDoorStatecon parámetros:bOpen (bool),Speed (float). - En
BP_Door, en Class Settings agrega la interfaz. - Implementa el evento/función de la interfaz dentro de
BP_Doory aplica la lógica (abrir/cerrar).
En el emisor (interruptor), usa el nodo de llamada de interfaz (por ejemplo SetDoorState (Message)) sobre una referencia. Si el actor no implementa la interfaz, no pasa nada (fallo seguro).
Event Dispatchers (eventos, suscripción y múltiples oyentes)
Un Dispatcher es un evento que un Blueprint “emite” y otros Blueprints pueden “escuchar” (bind). Es ideal para notificar cambios sin que el emisor llame directamente a una función concreta del receptor.
Cuándo usarlo: cuando un evento puede interesar a varios oyentes (una puerta, una luz, un sonido, un UI), o cuando quieres un patrón tipo “publicador/suscriptor”.
Conceptos clave
- Declare: creas el dispatcher en el emisor (por ejemplo
OnSwitchToggled). - Bind: el receptor se suscribe (por ejemplo la puerta se bindea al dispatcher del interruptor).
- Broadcast: el emisor dispara el evento y todos los suscritos reaccionan.
Los dispatchers pueden tener parámetros (por ejemplo bIsOn, Speed), lo que los hace perfectos para enviar datos junto con el evento.
Mini-proyecto: Interruptor y puerta (interfaz o dispatcher)
Objetivo: crear un BP_Switch que al activarse notifique a BP_Door para abrir/cerrar. Debe enviar parámetros como Speed y bOpen. Se proponen dos variantes: con interfaz (más directo y desacoplado) o con dispatcher (event-driven y con múltiples oyentes).
Preparación: BP_Door (variables y estructura)
Variables recomendadas
bIsOpen(bool): estado actual. Tooltip:Indica si la puerta está abierta. Categoría:Door|State. Exposición: Blueprint Read Only (normalmente).OpenSpeed(float): velocidad por defecto. Categoría:Door|Config. Exposición: Instance Editable (para ajustar por instancia).OpenYaw(float): ángulo objetivo de apertura (por ejemplo 90). Categoría:Door|Config. Instance Editable.
Lógica de movimiento (simplificada)
Implementa una función ApplyDoorState(bOpen, Speed) que:
- Actualiza
bIsOpen. - Calcula el yaw objetivo (0 si cierra,
OpenYawsi abre). - Interpola la rotación del componente de la puerta (por ejemplo con
Timelineo con interpolación en tick si ya lo tienes montado).
Ejemplo de firma (pseudo):
Function ApplyDoorState(bool bOpen, float SpeedOverride) -> voidNota: si SpeedOverride es menor o igual a 0, puedes usar OpenSpeed como fallback.
Variante A: Comunicación con Blueprint Interface (recomendada para desacoplar)
Paso 1: Crear la interfaz
- Crea
BPI_DoorControl. - Agrega función
SetDoorStatecon parámetros:bOpen (bool),Speed (float).
Paso 2: Implementar en BP_Door
- En
BP_Dooragrega la interfaz en Class Settings. - Implementa
SetDoorStatey dentro llama aApplyDoorState(bOpen, Speed).
Paso 3: Configurar BP_Switch (variables y edición)
En BP_Switch crea:
bIsOn(bool): estado del interruptor. Categoría:Switch|State. Read Only para otros (opcional).DoorTarget(Object Reference): tipo Interface (BPI_DoorControl). Categoría:Switch|Links. Instance Editable para asignar desde el editor.DoorSpeed(float): velocidad enviada a la puerta. Categoría:Switch|Config. Instance Editable. Tooltip:Velocidad enviada a la puerta; 0 usa la velocidad por defecto de la puerta.
Importante: al usar una variable de tipo interfaz, puedes asignar cualquier actor que implemente esa interfaz (no solo una clase concreta).
Paso 4: Activación del interruptor y envío del mensaje
- Cuando el jugador interactúe (por ejemplo por overlap + input, o un evento de interacción ya existente en tu proyecto), invierte
bIsOn. - Decide el estado de puerta: por ejemplo
bOpen = bIsOn. - Llama
SetDoorState (Message)sobreDoorTargetconbOpenyDoorSpeed.
Si DoorTarget no está asignado, el mensaje no hará nada; aun así, conviene validar con Is Valid para depuración.
Variante B: Comunicación con Event Dispatcher (ideal para múltiples oyentes)
Paso 1: Crear dispatcher en BP_Switch
En BP_Switch crea un dispatcher:
OnSwitchToggledcon parámetros:bIsOn (bool),Speed (float).
Paso 2: Emitir el evento
- Al activar el interruptor, actualiza
bIsOn. - Llama
OnSwitchToggled.BroadcastpasandobIsOnyDoorSpeed.
Paso 3: Hacer que la puerta se suscriba (Bind)
Necesitas que la puerta tenga una referencia al interruptor (asignada desde el editor o encontrada por tag/overlap). En BP_Door:
- Crea variable
SwitchSourcede tipoBP_Switch Object Reference(o una clase base de interruptor si la tienes). Marca Instance Editable. - En un punto de inicialización (por ejemplo al comenzar), si
SwitchSourcees válido, usaBind Event to OnSwitchToggled. - Crea un evento manejador (custom event) que reciba
bIsOnySpeed, y llame aApplyDoorState(bIsOn, Speed).
Ventaja: puedes tener varias puertas escuchando al mismo interruptor, o un interruptor que notifica a puerta + luz + sonido sin que el interruptor conozca sus clases.
Asignación y pruebas en el nivel (para ambas variantes)
- Coloca una instancia de
BP_Doory una deBP_Switchen el nivel. - Ajusta en la puerta:
OpenYawyOpenSpeed(Instance Editable). - Si usas interfaz: en el interruptor asigna
DoorTargetapuntando a la puerta. - Si usas dispatcher: en la puerta asigna
SwitchSourceapuntando al interruptor. - Ajusta
DoorSpeeden el interruptor para probar overrides (por ejemplo 0 para usar default, o 120 para abrir más rápido). - Ejecuta y activa el interruptor: verifica que el estado y la velocidad se transmiten correctamente.
Tabla rápida: ¿Casting, Interfaz o Dispatcher?
| Mecanismo | Cuándo usar | Dependencia | Soporta múltiples receptores |
|---|---|---|---|
| Casting | Cuando necesitas un tipo exacto y control directo | Alta | No (normalmente 1 a 1) |
| Interface | Cuando quieres llamar acciones sin conocer la clase concreta | Baja | 1 a 1 por llamada (puedes llamar a varios si tienes referencias) |
| Dispatcher | Cuando quieres emitir eventos y que otros se suscriban | Media-baja (según cómo obtengas la referencia) | Sí |
Errores comunes y cómo evitarlos
- Referencias nulas (None): si una variable no está asignada, cualquier acceso fallará. Usa
Is Validy tooltips claros indicando que debe asignarse. - Buscar actores constantemente: evita llamar
Get All Actors...repetidamente. Guarda la referencia una vez. - Exponer demasiado: no marques todo como Blueprint Read/Write. Expón solo lo que de verdad debe configurarse o consultarse.
- Acoplamiento excesivo por casting: si notas muchos
Cast To ...entre sistemas, considera migrar a interfaces o dispatchers.