Objetivo del proyecto integrador
Vas a construir un prototipo jugable pequeño (vertical slice) que conecte sistemas típicos de gameplay en un solo nivel: un objetivo claro, interacción por trazado (trace), coleccionables con contador, un obstáculo que cause daño y una condición de victoria/derrota. La meta no es “hacerlo grande”, sino hacerlo coherente, testeable y bien comunicado entre Blueprints.
Reglas de diseño para este capítulo
- Comunicación coherente entre Blueprints usando Blueprint Interfaces y/o Event Dispatchers (evita casts en cadena).
- Evitar lógica innecesaria en
Tick. Solo usarlo si es imprescindible (y con un motivo claro). - Validar con pruebas: casos normales y bordes (sin objetivos, múltiples pickups, reinicio).
Arquitectura mínima (qué Blueprints vas a crear)
Para mantener el proyecto ordenado, usa estos actores/clases (nombres sugeridos):
- BP_PlayerCharacter: movimiento ya existente + interacción + salud.
- BP_PlayerController (opcional): si prefieres centralizar input de interacción.
- BP_GameMode: reglas del nivel (victoria/derrota) y spawn.
- BP_GameState o BP_PlayerState: estado replicable/central (contador de pickups, objetivo). En singleplayer puedes usar GameState igualmente por claridad.
- WBP_HUD: UI en juego (salud, pickups, objetivo).
- WBP_EndScreen: pantalla de victoria/derrota con reinicio.
- BP_Pickup: coleccionable.
- BP_Hazard: obstáculo que daña (por overlap).
- BP_Goal: zona/actor de finalización (requiere X pickups).
- BPI_Interactable: interfaz para interactuar.
Nota de coherencia: el jugador solo “sabe” que algo es interactuable si implementa BPI_Interactable. El resto de lógica (sumar pickups, validar victoria) se decide en un lugar central (GameMode/GameState), no en el pickup.
Entregable 1: Configuración del nivel (layout y objetivos)
Paso a paso
- Crea un nivel pequeño con un camino claro: inicio → pickups → obstáculo → meta.
- Coloca 3–10 pickups visibles y una zona de meta (BP_Goal).
- Coloca 1–3 hazards (BP_Hazard) en puntos donde el jugador deba esquivar.
- Añade un PlayerStart y asegúrate de que el GameMode del nivel sea tu BP_GameMode.
Variables de diseño recomendadas
| Elemento | Variable | Ejemplo |
|---|---|---|
| BP_GameMode | RequiredPickups | 5 |
| BP_PlayerCharacter | MaxHealth, Health | 100 |
| BP_Hazard | DamageAmount, DamageCooldown | 25, 0.5 |
Evita Tick: el nivel no necesita lógica por frame. Todo debe dispararse por eventos (overlap, interacción, cambios de estado).
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
Descargar la aplicación
Entregable 2: Personaje (salud y eventos de daño)
El personaje debe poder recibir daño, actualizar UI y disparar derrota al llegar a 0.
Paso a paso (BP_PlayerCharacter)
- Agrega variables:
MaxHealth(float/int),Health. - En
BeginPlay: setHealth = MaxHealth. - Crea un Event Dispatcher en el personaje:
OnHealthChanged(CurrentHealth, MaxHealth). - Crea una función
ApplyDamageSimple(DamageAmount)que:- Reste vida con clamp a 0.
- Llame
OnHealthChanged. - Si
Health == 0, notifique derrota al sistema central (GameMode) con una llamada clara (por ejemplo, una función en GameMode:RequestDefeat).
Comunicación recomendada: el personaje no debería crear UI ni decidir pantallas; solo reporta su estado. El GameMode decide el final de partida.
Entregable 3: Sistema de interacción con trazado (trace) + interfaz
La interacción será “mirar y presionar interactuar”. No uses Tick para “escaneo continuo” si no lo necesitas; puedes trazar solo cuando el jugador presiona el botón, o trazar a intervalos con un Timer si quieres resaltar objetos.
Crear la interfaz BPI_Interactable
Crea BPI_Interactable con estas funciones:
CanInteract(Interactor) -> boolInteract(Interactor)GetInteractText() -> Text(opcional para UI)
Paso a paso (trazado al presionar)
- En BP_PlayerCharacter (o Controller), crea una acción de input “Interact”.
- Al presionar:
- Obtén la cámara (o el punto de vista) y calcula
StartyEnd(distancia 200–400). - Haz un
LineTraceByChannel(oSphereTracesi quieres tolerancia). - Si hay hit: toma
Hit Actory verificaDoes Implement Interface (BPI_Interactable). - Si implementa: llama
CanInteract. Si true, llamaInteractpasandoselfcomo Interactor.
- Obtén la cámara (o el punto de vista) y calcula
// Pseudoflujo en Blueprints (conceptual) Input Interact -> GetViewLocation/Rotation -> LineTrace -> HitActor -> Implements BPI_Interactable? -> CanInteract(self) -> Interact(self)Evita casts: no hagas “Cast to BP_Pickup” desde el jugador. Si mañana agregas una puerta, no quieres tocar el jugador.
Entregable 4: Pickups + contador central
El pickup debe ser interactuable y, al recogerse, debe incrementar un contador global del nivel. Ese contador alimenta la UI y la condición de victoria.
Estado del contador: ¿GameState o PlayerState?
- Singleplayer: puedes guardar
CollectedPickupsen GameState para que sea accesible desde UI y otros actores. - Si planeas multijugador luego: PlayerState es mejor para contadores por jugador.
En este prototipo, usa BP_GameState con:
CollectedPickups(int)- Event Dispatcher:
OnPickupsChanged(NewValue)
BP_Pickup (implementa BPI_Interactable)
- Componentes: StaticMesh + Collision (para que se pueda apuntar/tracear).
- Variables:
PickupValue(int, default 1),bConsumed(bool). CanInteract: retorna!bConsumed.Interact:- Si ya consumido, return.
- Marca
bConsumed = true. - Llama a una función del GameState:
AddPickups(PickupValue). - Desactiva colisión y oculta el mesh, o destruye el actor.
BP_GameState: función AddPickups
AddPickups(Amount): suma, actualizaCollectedPickups, disparaOnPickupsChanged.
Detalle importante: el pickup no decide victoria. Solo reporta “se recogió”. La regla “cuántos necesito” vive en GameMode.
Entregable 5: Obstáculo que causa daño (hazard) sin spam
El hazard dañará por superposición, pero debe evitar “daño por frame” incontrolado. Implementa un cooldown por actor que entra.
BP_Hazard (daño por overlap con cooldown)
- Componentes: Collision (Box/Sphere) + Mesh (opcional).
- Variables:
DamageAmount,DamageCooldown. - Estructura: un
MapdeActor -> LastDamageTime(o unSetde actores en cooldown con Timer). - En
OnComponentBeginOverlap:- Si OtherActor es el jugador (o implementa una interfaz de “Damageable” si quieres extender): aplica daño si no está en cooldown.
- Registra el tiempo y/o programa un Timer para permitir daño de nuevo.
// Idea de cooldown (conceptual) OnOverlap(Player): if Now - LastDamageTime[Player] >= DamageCooldown: Player.ApplyDamageSimple(DamageAmount); LastDamageTime[Player]=NowEvita Tick: no uses Tick para revisar overlaps. Overlap events + cooldown resuelven el problema.
Entregable 6: UI (HUD) conectada por eventos, no por polling
La UI debe reaccionar a cambios (vida, pickups) en lugar de consultar valores cada frame.
WBP_HUD: elementos mínimos
- Texto o barra de vida.
- Texto de pickups:
Collected / Required. - Texto de objetivo (opcional): “Recolecta X y llega a la meta”.
Conexión recomendada (event-driven)
- En BP_PlayerController o BP_PlayerCharacter en
BeginPlay: crea el widget HUD y añádelo al viewport. - Suscribe el HUD a:
PlayerCharacter.OnHealthChangedGameState.OnPickupsChanged
- Cuando se disparen, el HUD actualiza sus textos/barras.
Consejo: si el HUD necesita RequiredPickups, léelo desde GameMode (o expón una variable en GameState inicializada por GameMode al comenzar).
Entregable 7: Condición de victoria/derrota + pantalla final
La victoria ocurre cuando el jugador llega a la meta y tiene suficientes pickups. La derrota ocurre cuando la vida llega a 0. Ambas deben terminar en una pantalla final con opción de reiniciar.
BP_Goal (meta interactiva o por overlap)
Tienes dos opciones:
- Opción A (por overlap): al entrar en la zona, se evalúa si cumple requisitos.
- Opción B (por interacción): el jugador debe presionar interactuar en la meta (útil para mostrar “Te faltan X”).
Recomendación: Opción B usando BPI_Interactable, así reutilizas el sistema de interacción.
BP_Goal implementando BPI_Interactable
CanInteract: true si el interactor es el jugador (o siempre true).Interact:- Obtén
CollectedPickupsdel GameState. - Obtén
RequiredPickupsdel GameMode (o GameState). - Si cumple: llama a GameMode
RequestVictory. - Si no cumple: opcionalmente dispara un mensaje UI (por ejemplo, un dispatcher en HUD o un “toast” simple).
- Obtén
BP_GameMode: control del fin de partida
- Variables:
bGameEnded(bool). - Funciones:
RequestVictory,RequestDefeat. - En cada función:
- Si
bGameEnded, return (evita dobles finales). - Set
bGameEnded = true. - Crear y mostrar WBP_EndScreen con un estado (Victory/Defeat).
- Deshabilitar input del jugador o cambiar a UI Only.
- Si
WBP_EndScreen
- Texto grande: “Victoria” o “Derrota” (sin depender de Tick).
- Botón “Reiniciar”: llama a
OpenLevelcon el nombre del nivel actual. - Botón “Salir” (opcional):
QuitGame.
Reinicio limpio: al reiniciar con OpenLevel, el estado se reconstruye. Asegúrate de que el contador se inicialice en 0 en BeginPlay del GameState o al iniciar el nivel (por ejemplo, GameMode lo setea).
Pruebas: casos normales y bordes (checklist)
Casos normales
- Recolectar 1 pickup incrementa el contador y actualiza HUD.
- Recibir daño reduce vida y actualiza HUD.
- Con pickups suficientes, interactuar con la meta muestra victoria.
- Con vida 0, se muestra derrota y se bloquea el control.
Casos borde
- Sin objetivos/pickups en el nivel:
- Si
RequiredPickupses 0, la meta debe permitir victoria inmediata. - Si
RequiredPickups> 0 pero no hay pickups colocados, el juego debe seguir funcionando (solo no se podrá ganar). Considera mostrar “Faltan X” al interactuar con la meta.
- Si
- Múltiples pickups recogidos rápido:
- Verifica que no se duplique el conteo por doble interacción (usa
bConsumedy desactiva colisión/actor).
- Verifica que no se duplique el conteo por doble interacción (usa
- Daño en hazard:
- Permanece dentro del hazard: el cooldown debe evitar que la vida caiga a 0 instantáneamente.
- Entrar/salir repetidamente: el daño debe ser consistente.
- Reinicio:
- Tras reiniciar, vida vuelve a Max y pickups vuelven a 0.
- La pantalla final no debe persistir.
Mejoras opcionales (mismo proyecto, solo Blueprints)
- Checkpoint: guarda un transform al pasar por un trigger; al morir, respawnea ahí en lugar de reiniciar el nivel.
- Sonidos: SFX al recoger pickup, recibir daño, victoria/derrota (Audio Component o Play Sound at Location).
- Efectos visuales básicos:
- Pickup: rotación suave con Timeline (en lugar de Tick) o material emissive.
- Daño: flash en pantalla (UMG) o cambio breve de material en el personaje.
- Resaltado de interactuables: al mirar un objeto, mostrar outline o cambiar material; implementa un Timer que trace cada 0.1s en lugar de Tick.
- Mensajes de objetivo: un widget pequeño tipo “toast” que diga “Te faltan X pickups” al intentar la meta.