Los peligros de entorno juegan un papel importante en la configuración de la jugabilidad. Al usar peligros y trampas, añades consecuencias para el jugador y aumentas la dificultad y la tensión a medida que avanzas por un rompecabezas o nivel.
En esta parte de la serie de tutoriales, crearás una trampa de pinchos y una trampa de fuego que pueden dañar al jugador. Después, conectarás tu trampa de fuego y cambiarás los objetos de la jugabilidad para crear una nueva mecánica de jugabilidad y un nuevo rompecabezas.
Ahora que el jugador puede recibir daño y perder toda su salud, también configurarás una condición de fallo que finalice y reinicie el juego, dando a los jugadores la oportunidad de intentarlo de nuevo.
Antes de empezar
Asegúrate de que comprendes los temas ya tratados en secciones anteriores de El diseño de una aventura de puzles:
aspectos básicos de los blueprint, como variables, funciones, grafos de eventos e incorporación de nodos.
Usar eventos de interfaz de blueprint para hacer que un interruptor active otro objeto de jugabilidad.
Necesitarás los siguientes recursos de Cómo crear una llave y Rompecabezas: interruptores y cubos:
Material
M_BasicColore instancia de materialM_BasicColor_RedInterfaz de Blueprint
BPI_InteractionClase de blueprint
BP_Switch
Compila un conjunto de clases de blueprint relacionadas
A lo largo de esta serie de tutoriales, te has encontrado con recursos de Unreal Engine que usan relaciones padre-hijo y herencia. La herencia consiste en crear una nueva clase hijo que reutilice y amplíe las funciones de una clase padre existente. La clase hijo puede ampliar esas características sin alterar la clase padre. La herencia te ahorra tiempo al reutilizar funciones útiles en muchos recursos en lugar de tener que añadirlas manualmente a cada nuevo recurso.
Tus recursos de instancia de material heredan las funciones de sus materiales padre. En muchos de tus blueprints, has creado componentes que heredan datos de transformación de un componente padre.
Los juegos usan distintos tipos de peligros, pero a menudo comparten las mismas funciones principales. Un blueprint de trampa padre puede definir esas funciones compartidas, mientras que cada blueprint de trampa hijo amplía esas funciones, añadiendo diferentes elementos visuales y comportamientos.
Tu trampa base (padre) necesita detectar la superposición del jugador y usar la mecánica de juego de daño para disminuir la salud del jugador con el tiempo. Después, crearás trampas hijo (o subclases) para ampliar las funciones de la trampa base y añadir elementos visuales o comportamientos adicionales. La trampa de pinchos añade mallas estáticas adicionales a su apariencia y la trampa de fuego añade un efecto de fuego y un comportamiento que hace que se active o desactive.
Tu nivel aún se encuentra en la etapa de bloqueo, así que céntrate en crear una versión simplificada de cada trampa que siga informando del futuro diseño visual.
Crea el blueprint de trampa base
En primer lugar, crea la clase de blueprint de trampa base como padre y referencia de tus trampas especializadas.
Para crear un blueprint que defina funciones de trampa comunes, sigue estos pasos:
En el explorador de contenido, ve a la carpeta Contenido > AdventureGame > Diseñador > Blueprints y crea una nueva carpeta llamada
Trampas.En la carpeta Trampas, haz clic derecho o clic en Añadir y crea una nueva clase de blueprint.
En la ventana
Elegir clase padre, haz clic en Actor.Dale a esta clase el nombre
BP_TrapBasey ábrela.
Añade componentes
Para la trampa base, crearás una malla estática de estilo bloqueado para mostrar los límites de la trampa. Todas las trampas también necesitan un volumen de colisión para saber cuándo el jugador las pisa.
Para crear los componentes de física de la trampa base, sigue estos pasos:
En la pestaña Componentes, haz clic en Añadir, y busca y añade una forma de malla estática Cubo.
Dale al componente de malla el nombre
TrapBase.En el panel Detalles debajo de Transformar, cambia la escala del cubo a
2,2,0.1para crear una base cuadrada plana.En la pestaña Componentes, con TrapBase seleccionado, haz clic en Añadir y busca y selecciona un componente de Colisión de caja.
Dale al componente de colisión el nombre
TrapTrigger.Este es el volumen de colisión que usarás para detectar cuándo el jugador está parado sobre la trampa.Al igual que con
BP_Switch, estás vinculando el componente de colisión a la malla, por lo que si quieres cambiar el tamaño de la trampa, el área del activador se ajustará automáticamente.En el panel Detalles debajo de Transformar, cambia las siguientes propiedades para crear una caja de colisión grande encima de la malla base:
Establece Ubicación en
0,0,400.Establece Escala en
1.5,1.5,12.
Añade variables
Todas las trampas también necesitan propiedades editables que permitan personalizar:
Si el peligro está activo o inactivo.
El daño que la trampa inflige al jugador.
El intervalo de daño o el tiempo entre impactos.
Además, la trampa necesita saber quién ha colisionado con ella.
Para añadir propiedades comunes a la trampa base, sigue estos pasos:
En la pestaña My Blueprint, crea las siguientes variables:
Nombre de variable
Tipo
Categoría
Valor predeterminado
Activa
Booleano
Configuración
Verdadero
BaseDamage
Float
Configuración
5.0
DamageInterval
Float
Configuración
1,0
Después de crear una variable, compila tu blueprint para añadir un valor predeterminado.
Haz clic en el icono del ojo de cada variable para abrir el ojo y hacer que las tres variables sean públicas y editables.
Añade una variable llamada
OtherActory cámbiale el tipo a Actor (Object Reference).
Crea una función para infligir daño
Ahora que ya tienes las propiedades base de la trampa, puedes empezar a crear su comportamiento. Todas las trampas deberían reducir los puntos de impacto (PI) del jugador a intervalos regulares cuando el jugador se superpone con el volumen de colisión.
Unreal Engine cuenta con soluciones integradas para muchas mecánicas de jugabilidad habituales, como la aplicación y la recepción de daño.
Para la trampa, usarás el nodo de función Apply Damage integrado. Para organizar la lógica de gestión del daño, crearás tu propia función que llama a Apply Damage en todos los personajes que toquen la trampa si la trampa está activa.
Para crear una función que inflija daño con trampas al jugador, sigue estos pasos:
En la sección Funciones, haz clic en Añadir. Dale a esta función el nombre
fnApplyDamageToTargetsy abre su grafo.Solo quieres infligir daño si la trampa está activada y activa, así que añade un nodo Branch donde Condition sea una referencia (Get) a la variable Activa.
Más adelante en este tutorial, añadirás algunos enemigos PNJ, por lo que es posible que varios actores estén sobre la trampa a la vez. Entonces, cuando la trampa esté activa, recorre en bucle una matriz de todos los actores que toquen la trampa:
Conecta el pin Verdadero del nodo Branch a un nodo For Each Loop.
Para la entrada Array del bucle, debes crear una matriz con todos los actores superpuestos. Unreal Engine hace esto por ti: añade un nodo Get Overlapping Actors (TrapTrigger). El nodo incluye una referencia a TrapTrigger como su objetivo.
En el nodo Get Overlapping Actors, cambia Filtro de clase a Personaje para que se puedan añadir personajes jugadores y PNJ a la matriz.
Para cada elemento de la matriz o cada iteración del bucle, inflige la cantidad de daño establecida en la variable BaseDamage al actor en ese elemento de la matriz. Para ello, conecta un nodo Apply Damage al cuerpo del bucle.
La función Apply Damage proviene de la biblioteca de estadísticas de juego de Unreal Engine. El icono en la esquina superior derecha significa que la función puede usarse en juegos en red y puede ejecutarse en el servidor.
Configura el nodo Apply Damage:
Para el pin Actor dañado, conecta el elemento de matriz del bucle.
Para el pin Daño base, conecta una referencia a la variable BaseDamage.
6. Guarda y compila tu blueprint.
Tu función fnApplyDamageToTarget completa debería tener el siguiente aspecto:
Si copias y pegas este fragmento en el grafo correspondiente de tu proyecto, conecta el nodo de entrada de la función al nodo Branch.
Crea un temporizador que inflija daño con el tiempo
A continuación, tienes que hacer que la trampa llame a la función que inflige daño a intervalos regulares. Para ello, usarás una de las funciones de temporizador de Unreal Engine para crear un temporizador.
En este blueprint, usarás el nodo Set Timer by Function Name:
Este nodo crea un temporizador y vincula una función a ese temporizador para que, cuando venza el temporizador, el nodo llame a la función y ejecute todas las acciones de esa función.
Para configurar un temporizador cuando comience la partida, sigue estos pasos:
Ve a la pestaña Grafo de eventos de
BP_TrapBase. Elimina los nodos Event ActorBeginOverlap y Event Tick proporcionados.Antes de que la trampa realice ninguna acción, querrás comprobar si está activa. Desde el nodo Event BeginPlay, añade un nodo Branch donde Condition sea una referencia a la variable Activa.
Desde el pin Verdadero del nodo Branch, crea un nodo Set Timer by Function Name.
Configura el nodo Timer:
En el pin Tiempo, conecta una referencia a la variable DamageInterval.
Haz clic en el cuadro de texto junto a Nombre de función e introduce
fnApplyDamageToTarget.Garantiza que hayas escrito correctamente el nombre de la función o la lógica no se ejecutará correctamente.
Activa Bucles.
Los nodos Set Timer emiten un valor de retorno llamado un Controlador del temporizador que actúa como un número de reconocimiento o controlador para el temporizador. Para detener, pausar o reanudar el temporizador, debes hacer referencia a este controlador del temporizador, así que guárdalo en una nueva variable:
En el panel My Blueprint, crea una nueva variable llamada
TimerHandler. Cambia su tipo a Timer Handle.Añade un nodo Set Timer Handler y conéctalo a los pines de valor de retorno y de ejecución de Set Timer by Event.
Cuando Unreal Engine crea un temporizador, este empieza a ejecutarse inmediatamente, por lo que tendrás que pausar el temporizador hasta que un personaje pise la trampa. Conecta un nodo Pause Timer by Handle y dale tu TimeHandler.
Guarda y compila tu blueprint.
También puedes crear temporizadores con un nodo Set Timer by Event. En este caso, usarías la lista de acciones del nodo para añadir un evento personalizado y la usarías como delegado para vincular acciones al temporizador.
Los eventos personalizados son bloques de lógica reutilizables con nombre, similares a las funciones. A diferencia de las funciones, pueden contener retrasos, nodos de cronograma y otras acciones latentes, por lo que es posible que debas usar este método a medida que tu juego sea más complejo.
Conecta el pin de delegado cuadrado de un evento para pasar una referencia de ese evento al nodo Timer. Esto no activa el evento, sino que almacena el evento y sus acciones para más adelante (cuando venza el intervalo de tiempo).
Inicia y detén el daño
Has creado y puesto en pausa el temporizador de daño, por lo que está listo y en espera. Ahora, haz que el daño se reanude cuando un personaje pise el volumen de colisión de la trampa y pausa el daño cuando los personajes dejen de superponerse con el volumen.
Para añadir lógica que inicie el daño, sigue estos pasos:
En el panel Componentes, haz clic derecho en el componente TrapTrigger, ve a Añadir evento y selecciona Añadir OnComponentBeginOverlap.
Después del evento, conecta un nodo Set Other Actor para guardar el actor superpuesto en la variable.
Conecta los pines de evento y Otro actor del nodo Set.
Conecta un nodo fnApplyDamageToTarget para que el personaje reciba daño inmediatamente al tocar la trampa.
Conecta un nodo Unpause Timer by Handle para reanudar el temporizador y los intervalos de daño. Para su Handle Input, conecta una referencia a la variable TimerHandler.
Para añadir una lógica que detenga el daño con el tiempo, sigue estos pasos:
Haz clic derecho en el componente TrapTrigger, ve a Añadir evento > Al superponerse el final del componente.
Después del evento, conecta un nodo Pause Timer by Handle asignándole otra vez una referencia a TimerHandler.
Guarda y compila tu blueprint.
Ahora la trampa creará, iniciará y pausará un temporizador de daño.
El grafo de evento BP_TrapBase terminado debería tener el siguiente aspecto:
Para obtener más información sobre temporizadores y su gestión, consulta la sección Gameplay Timers.
Prueba la trampa base
Para probar la trampa, añade un mensaje de cadena que informe en pantalla cuando la trampa inflija daño.
Para que aparezca un mensaje en pantalla que indique que la trampa está funcionando como es debido, sigue estos pasos:
En
BP_TrapBase, ve a la pestaña fnApplyDamageToTarget.En el grafo de la función, conecta un nodo Print String después del nodo Apply Damage.
Cambia En cadena a
¡Jugador golpeado!Haz clic en la flecha de la parte inferior del nodo Print String para mostrar más opciones y cambia la duración a
5. Esto hace que sea más fácil ver los impactos de daño a lo largo del tiempo.Compila y guarda el blueprint. En el explorador de contenido, arrastra una instancia de
BP_TrapBasea tu nivel.Reproduce el nivel y pisa la trampa. Un nuevo mensaje de «¡Jugador golpeado!» debería aparecer cada segundo.
Crea una subclase de trampa de pinchos
Ahora que has completado tu clase padre, es el momento de empezar a crear subclases.
En primer lugar, crearás una trampa de pinchos que modificará el aspecto de la trampa base añadiendo algo de lenguaje de formas. Una trampa plana no parece peligrosa, pero el jugador interpretará un objeto con pinchos como algo que podría lastimarle.
Para crear una trampa de pinchos, sigue estos pasos:
En el explorador de contenido, en la carpeta Trampas, haz clic derecho en
BP_TrapBasey selecciona Crear clase hija de blueprint.Dale a la clase de blueprint el nombre
BP_TrapSpikesy ábrela.En la pestaña Componentes, selecciona DefaultSceneRoot, haz clic en Añadir y selecciona Cono.
Cambiarás el tamaño y la posición de los conos para que quepan en cuatro filas de cuatro conos cada una (o 16 en total).
En la sección Transformar del panel Detalles del cono, cambia las siguientes propiedades:
Cambia Ubicación a
-75,-75,25.Cambia Escala a
0.5,0.5,0.4.
Ahora hay un pincho más pequeño en la esquina de la malla base.
Para añadir un poco de contraste visual, en la sección Materiales, usa el menú desplegable para cambiar el material del cono a
M_BasicColor_Red.Selecciona y duplica (Ctrl + D) el cono tres veces, trasladando cada cono 50 unidades para que queden alineados en una fila a un lado de la malla base.
Mantén pulsado Ctrl para seleccionar los cuatro conos y duplicarlos. En el panel Componentes, selecciona los cuatro nuevos conos (que tendrán los sufijos numéricos más grandes) y muévelos 50 unidades. Repite este proceso dos veces más para crear una cuadrícula de conos de 4x4.
Debido a las pendientes y los ángulos de los pinchos, al jugador le resultaba difícil salir de la trampa. Para evitar que el jugador aterrice entre los pinchos, añade un suelo invisible en la parte superior de los pinchos:
En la pestaña Componentes, duplica la malla TrapBase y nómbrala
InvisFloor.Mueve el suelo hacia arriba de forma que solo se vean las puntas de los pinchos por encima del suelo.
En la sección Collision del panel Detalles, asegúrate de que Preajustes de colisión esté configurado como BlockAllDynamic. Esto bloquea el paso de todos los actores a través de la malla.
En la sección Renderizado, desactiva Visible. Esto oculta la malla en los visores y durante el juego.
En la pestaña Componentes, selecciona la malla TrapBase. En la sección Renderizado del panel Detalles, habilita Oculto en el juego. Esto mantiene la malla visible en los visores, pero la oculta durante el juego, por lo que solo verás los pinchos.
Guarda y compila tu blueprint.
La subclase de trampa de pinchos tiene todo el comportamiento de tu trampa base, por lo que también imprime mensajes «¡Jugador golpeado!» cuando la trampa está funcionando. Arrastra una instancia de BP_TrapSpikes a tu nivel y pruébala.
Crea una subclase de trampa de fuego
A continuación, crearás una trampa que amplía el comportamiento de la trampa base. Una trampa de fuego añade un peligro que el jugador puede desactivar con un interruptor. Esto es una mecánica de jugabilidad que puedes convertir en un nuevo rompecabezas.
En Rompecabezas: interruptores y cubos, creaste la interfaz de blueprint BPI_Interaction que un interruptor puede usar para activar o desactivar otros objetos del jugabilidad. También puedes usar esta interfaz en un blueprint de trampa para que un interruptor pueda cambiar la variable Activa de la trampa durante el juego.
Primero necesitarás un nuevo material para usarlo cuando la trampa esté desactivada.
Si quieres crear un material negro para la trampa de fuego, sigue estos pasos:
En el explorador de contenido, ve a la carpeta AdventureGame > Diseñador > Materiales.
Haz clic derecho en
M_BasicColory selecciona Crear instancia de material.Dale a la instancia de material el nombre
M_BasicColor_Blacky ábrela.Amplía Valores de parámetros vectoriales globales, activa Color y haz clic en la muestra de color para cambiarla a un gris oscuro (sRGB hexadecimal =
3D3B3BFF). Esto se ve mejor en el juego que el negro puro.Guarda y cierra la instancia de material.
Para crear una subclase de trampa de fuego, sigue estos pasos:
En el explorador de contenido, haz clic derecho en
BP_TrapBasey selecciona Crear clase hija de blueprint.Dale al blueprint el nombre
BP_TrapFirey ábrelo.Cambia el color de la malla base para que represente una trampa de fuego. Selecciona el componente TrapBase y, en la sección Materiales del panel Detalles, cambia el material a
M_BasicColor_Red.Encima del visor, haz clic en Ajustes de clase.
En la sección Interfaces del panel Detalles, junto a Interfaces implementadas, haz clic en Añadir y busca y selecciona
BPI_Interaction.En el panel My Blueprint, las funciones de evento fnBPISwitchOff y fnBPISwitchOn aparecen en la sección Interfaces.
Al igual que con
BP_Switch, configura materiales personalizables para la trampa de fuego:En la sección Variables del panel My Blueprint, crea dos variables llamadas
OffMaterialyOnMaterial.Cambia su tipo a Material Interface (Object Reference).
Haz clic en sus iconos de ojo para hacerlos públicos y editables.
Cambia su Categoría a Configuración.
Compila y establece los siguientes valores predeterminados:
OffMaterial:
M_BaseColor_BlackOnMaterial:
M_BaseColor_Red
Guarda y compila el blueprint para poder usar los eventos de interfaz en el grafo de eventos de las trampas.
Amplía el comportamiento de las trampas
Al igual que cuando creaste la plataforma móvil en Rompecabezas: plataformas móviles, tendrás que configurar el grafo de eventos de la trampa para que realice las siguientes acciones cuando un interruptor llame a fnBPISwitchOn y fnBPISwitchOff:
Activa o desactiva la trampa.
Cambia el material de la trampa.
Con la plataforma móvil, necesitabas que la plataforma empezara a moverse cuando el jugador activaba el interruptor. Para la trampa, necesitas lo contrario: la trampa está activa cuando el nivel comienza y debe desactivarse cuando el jugador activa el interruptor.
Para añadir una lógica que desactive las trampas de fuego cuando el jugador pulsa un interruptor, sigue estos pasos:
Ve a la pestaña Grafo de eventos de la trampa de fuego. En el panel My Blueprint, en la lista Interfaces, haz doble clic en fnBPIButtonOn para añadir un nodo de evento al grafo.
Las variables
BP_TrapBaseno aparecen en el panel My Blueprint, pero puedes acceder a ellas con la lista de acciones del nodo. Arrastra el pin Ejecución del nodo Event fnBPISwitchOn, busca la variableActivay selecciona Set Active. Mantén la opción Activa deshabilitada.Después del nodo Set, conecta un nodo Set Material (TrapBase) (en la sección Renderizado > Material de la lista de acciones).
En el nodo Set Naterial, conecta una referencia de la variable OffMaterial al pin Material.
Para añadir una lógica que active las trampas de fuego si se desactiva un interruptor, sigue estos pasos:
En la sección Interfaces, haz doble clic en Event fnBPISwitchOff para añadir ese nodo.
Después del evento, conecta un nodo de variable Set Active, pero esta vez habilita la opción Activa.
Después del nodo Set, conecta un nodo Set Material (TrapBase) y una referencia a OnMaterial.
Guarda y compila tu blueprint.
El grafo completo de eventos de la trampa de fuego debería tener este aspecto:
Añade una instancia de BP_TrapFire a tu nivel y pruébalo.
Actualiza el HUD con los PS del jugador
Es hora de reemplazar esos nodos Print String con información real para el jugador. Cambiarás el HUD para que informe de los puntos de salud (PS) del jugador en tiempo real.
Añade an una variable HP al HUD
Para añadir salud de jugador dinámica al HUD, sigue estos pasos:
En el explorador de contenido, abre el blueprint de widget
WBP_PlayerHUD. Asegúrate de que estás en la vista de diseñador.En Jerarquía, haz clic en el widget txtHP. En el panel Detalles, activa Variable y elimina 100 de la propiedad Texto.
Ve a la vista del grafo y configura una nueva función que establezca el valor de txtHP:
En la sección Funciones, añade una nueva función llamada fnSetHP.
Con la función seleccionada, en el panel Detalles, haz clic en + junto a Entradas.
Dale a la entrada el nombre
NewHPy cambia su tipo a Float.Más adelante, cambiarás el personaje jugable para que llame a esta función cuando reciba daño.
En el grafo de la función fnSetHP, después del nodo de entrada de la función, conecta un nodo SetText (Text).
Si no encuentras un nodo en la lista de acciones del nodo, desactiva Sensible al contexto.
Configura el nodo SetText (Text):
Para el objetivo, conecta una referencia a la variable txtHP. Este es el widget de texto que muestra la salud del jugador.
Para En texto, conecta el pin de entrada Nuevo PS del nodo de entrada de la función. Unreal Engine añade automáticamente un nodo To Text (Float) para convertir el valor.
Guarda y compila el blueprint de widget.
El grafo de la función fnSetHP completa tiene el siguiente aspecto:
Si copias este fragmento de blueprint en tu grafo, tendrás que conectar el nodo de entrada de la función a los nodos SetText y To Text.
Muestra los PS iniciales del jugador
Configura cualquier variable del HUD disponible antes de mostrarla. En este caso, conoces los PS iniciales del jugador, por lo que puedes mostrar esa información cuando se inicie la partida.
Para actualizar el blueprint del personaje jugable para que muestre sus PS en el HUD, sigue estos pasos:
En el explorador de contenido, abre tu blueprint
BP_AdventureCharacter. En el grafo de eventos, busca la lógica de Event Possessed.En el panel My Blueprint, amplía Grafos > Grafo de eventos y haz doble clic en el nodo Event Possessed para centrarte en él en el grafo.
Entre el nodo Set y el nodo Add to Viewport, conecta un nodo fnSetHP:
Para el objetivo, usa el pin de salida del nodo Set para el HUD sea el objetivo.
En Nuevo PS, vincula una referencia a la variable Salud del jugador.
Asegúrate de que el pin Objetivo del nodo Add to Viewport también se conecte a un nodo de variable del HUD.
En el panel My Blueprint, haz clic en la variable Salud. En el panel Detalles, cambia (o conserva) el valor predeterminado. Este tutorial usa 100 puntos de impacto iniciales.
Guarda y compila.
La nueva lógica de Event Possessed del jugador debería tener el siguiente aspecto:
Si vas a copiar esta lógica en tu proyecto, primero elimina el grupo lógico Event Possessed existente.
Ahora, el HUD mostrará la salud del jugador cuando empiece la partida. El último contenido de lógica que necesitas es actualizar el HUD cuando el jugador reciba daño. Para ello, tendrás que modificar la lógica de control de daños del personaje para que funcione con tu HUD.
Actualiza los PS del jugador después de recibir daño
Para gestionar el daño infligido al jugador, sigue estos pasos:
En la esquina inferior izquierda del grafo de eventos de
BP_AdventureCharacter, busca la sección de lógica con la etiqueta «Gestión de daño y muerte» que empieza con un nodo Event AnyDamage. Lo que vas a hacer es modificar esta sección para que ejecute tu propia lógica.Elimina todos los nodos que vienen después del nodo Branch. Conserva el nodo Branch.
Esta sección de lógica usa nodos de operador para realizar cálculos. Cuando el personaje reciba daño, el nodo Event AnyDamage se activa, transmitiendo información sobre el daño infligido, el tipo de daño y el controlador y actor que instigó el daño. A continuación, el daño se resta de la variable Salud del personaje. Una vez restada la salud, el nodo Branch comprueba si la salud del jugador ha llegado a 0.
Por ahora, quieres compilar una lógica que actualice el HUD cuando la salud del jugador sea superior a 0. Para ello, desde el pin Falso, conecta un nodo FnSetHP para enviar el nuevo valor de salud al HUD.
Configura el nodo fnSetHP:
Para el objetivo, conecta una referencia a la variable del HUD del personaje.
Para la entrada Nuevo PS, conecta una referencia a la variable Salud.
Guarda y compila tu blueprint.
Ahora el HUD muestra la salud actual del jugador y actualiza ese valor de salud cuando el jugador recibe daño.
Vuelve al blueprint BP_TrapBase y elimina los nodos Print String que hayas añadido al grafo de eventos de la trampa base.
¡Vuelve a reproducir tu juego y pruébalo!
Crea una condición de fallo y reaparición
Cuando el jugador se queda sin salud y es eliminado, conviene detener la partida y darle una oportunidad de volver a intentarlo. En este tutorial, desactivarás los controles del jugador, comunicarás al jugador que ha perdido la partida y cargarás el nivel.
En primer lugar, crearás un blueprint de widget de fin de partida que avisará al jugador de que ha sido eliminado.
Añade una pantalla de fin de partida
Para crear un blueprint de widget para tu pantalla de fin de partida, sigue estos pasos:
En el explorador de contenido, en la carpeta AdventureGame > Diseñador > Blueprint > Widget, haz clic derecho, ve a Interfaz de usuario, y selecciona Blueprint de widget.
En la ventana Elegir clase padre, haz clic en Widget de usuario.
Dale al blueprint de widget el nombre
WBP_EliminatedScreeny ábrelo.
Para configurar la IU de fin de partida, sigue estos pasos:
En la pestaña Paleta, busca el lienzo y arrastra un panel de lienzo hasta [WBP_EliminatedScreen] en la jerarquía. Al igual que con tu HUD, el lienzo es tu widget raíz.
El lienzo tendrá un mensaje de fin de partida sobre un efecto de desenfoque que hará que el texto sea más legible. En la pestaña Paleta, arrastra una superposición para que se convierta en un hijo del lienzo.
Con la superposición seleccionada, en la sección Ranura (ranura del panel Lienzo) del panel Detalles, amplía Anclajes y cambia los dos valores máximos (X e Y) a
1.El resto de propiedades de las ranuras (debajo de Anclajes) cambiarán a los ajustes de Compensación.
Al compilar el HUD, mantuviste todos los puntos de anclaje en una esquina para que, si cambiaba el tamaño de la pantalla, esos objetos permanecieran anclados al punto de anclaje. Ahora, la superposición está anclada a todo el cuadro delimitador del lienzo, por lo que se encoge o estira para adaptarse al tamaño de la pantalla.
Cuando cambiaste los ajustes del anclaje, el editor cambió algunos valores de compensación para mantener la forma predeterminada del panel de superposición. Para eliminar esto, cambia Compensar a la derecha y Compensar abajo a
0. Ahora la superposición ocupará toda la pantalla.En la pestaña Paleta, arrastra un widget de desenfoque del fondo para que se convierta en un hijo del panel Superposición.
Con el efecto de desenfoque seleccionado, en la sección Ranura (ranura de superposición) del panel Detalles, cambia:
Alineación horizontal a Rellenar horizontalmente.
Alineación vertical a Rellenar verticalmente.
En la sección Apariencia, cambia Intensidad de desenfoque a
5.En la pestaña Paleta, añade un widget de texto como hijo de la superposición.
Con el widget de texto seleccionado, en la sección Ranura (ranura de superposición) del panel Detalles, cambia:
Alineación horizontal a Alinear centro horizontalmente.
Alineación vertical a Alinear centro verticalmente.
En la sección Contenido, cambia Text a
Te han eliminado. Reiniciando el nivel.En la sección Apariencia , configura las siguientes propiedades para que el texto sea más grande y más fácil de leer:
Haz clic en la muestra de color que hay junto a Color y opacidad y elige un color para tu texto. En este tutorial se usa el rosa (color sRGB hexadecimal =
FF4D7AFF).Amplía el encabezado Fuente y cambia Tamaño a
60.Amplía Fuente > Ajustes del contorno y cambia Tamaño del contorno a
1.
12. Guarda y compila tu blueprint.
Crea la lógica para una condición de fallo
Ahora que tienes una pantalla de fin de partida, puedes modificar la clase de personaje para que la muestre cuando el jugador se quede sin PS. Cuando esto sucede, la ejecución pasa por el resultado Verdadero del nodo Branch con el que estabas trabajando antes.
Para gestionar la derrota de jugador, tendrás que hacer lo siguiente:
Desactiva la entrada del jugador para que el jugador no pueda moverse.
Muestra la pantalla de fin de partida.
Reinicia el nivel después de un tiempo establecido.
Para detener y cargar el juego cuando el jugador es eliminado, sigue estos pasos:
En
BP_AdventurePlayer, vuelve a la lógica de gestión de daño (empezando por Event AnyDamage) del blueprint de tu personaje.Después del pin de ejecución Verdadero del nodo Branch, conecta un nodo Do Once y un nodo Disable Input.
El jugador puede seguir recibiendo impactos aunque se le acabe la salud, por lo que el nodo Do Once garantiza que la lógica que sigue solo se ejecute una vez.
Para el pin Controlador de jugador del nodo Disable Input, conecta un nodo Get Player Controller (en la sección Juego > Jugador de la lista de acciones del nodo).
Hay varios nodos con el nombre Get Player Controller. Asegúrate de que el nodo tenga un pin de entrada de Índice de jugador. Un índice de 0 es el índice predeterminado para el primer personaje jugador generado en el nivel.
Después de desactivar el controlador del jugador, crea y muestra la pantalla de fin de partida:
Conecta un nodo Create Widget. En el nodo, cambia la clase a
WBP_EliminatedScreen.Conecta los pines Ejecucióny Valor devuelto del nodo del widget a un nodo Add to Viewport.
Añade un retraso, obtén el nombre del nivel actual y luego carga ese nivel:
Después del nodo Add to Viewport, conecta un nodo Delay y cambia la duración a
5segundos.Después del retraso, conecta un nodo Get Current Level Name.
Después de Get Current Level Name, conecta un nodo Open Level (by Name).
Conecta el pin Valor devuelto con el pin Nombre del nivel. El editor añade automáticamente un nodo de conversión de cadena a nombre.
Guarda y compila tu blueprint de jugador.
Esta sección del grafo de eventos BP_AdventureCharacter ahora debería tener el siguiente aspecto:
Si vas a copiar esta lógica en tu proyecto, primero elimina el grupo de nodos Damage Handling existente (incluidas las lógicas de Event AnyDamage y Event Destroyed).
Reproduce tu nivel para probarlo. Pisa una trampa, deja que tu personaje pierda todos sus PS y asegúrate de que la partida se reinicia correctamente.
Añade peligros a tus rompecabezas
En Rompecabezas: interruptores y cubos, aprendiste a diseñar mecánicas de jugabilidad que añaden dificultad, tensión, consecuencias y decisiones de riesgo-recompensa. Los peligros ambientales que dañan al jugador son una de las mecánicas que introduce estas consecuencias. Puedes usar las trampas de pinchos para añadir peligro y consecuencias adicionales a los primeros rompecabezas y obstáculos del nivel, y las trampas de fuego con interruptor automático pueden crear rompecabezas más dinámicos que hagan que el jugador interactúe con el entorno para revelar rutas seguras.
Al diseñar juegos, una parte clave para reducir la sobrecarga y mejorar la velocidad de desarrollo es encontrar múltiples formas diferentes de usar y combinar objetos de jugabilidad. En una sección anterior de esta serie de tutoriales, el interruptor funciona con plataformas para crear una ruta hacia adelante. Aquí, con el mismo interruptor, se pueden desactivar las trampas de fuego para revelar una ruta al jugador. Esto añade variedad al nivel sin necesidad de un sinfín de sistemas únicos.
De forma similar a la mecánica de juego de puertas y llaves que creaste antes en esta serie de tutoriales, la trampa de fuego se convierte en otra mecánica más que controla el ritmo del jugador y su acceso al entorno.
Crea un laberinto con trampas de fuego
En la Sala 2, combinarás interruptores y trampas de fuego para compilar un laberinto en el que el jugador deba desactivar con cuidado los peligros para descubrir y recoger la última llave.
A menudo ayuda crear primero los rompecabezas en papel. Como las trampas miden 1 x 1 m, en nuestra sala 2 de muestra cabe una cuadrícula de trampas de 7 x 9. Empieza dibujando una ruta a través de la cuadrícula que acabe en la llave. Después, divide la ruta en segmentos y coloca interruptores para controlar cada segmento.
Para añadir dificultad y crear más revelaciones y sorpresas, añade funciones arquitectónicas que bloqueen las líneas de visión. Por ejemplo, puedes colocar interruptores detrás de paredes o pilares para que el jugador los encuentre en la ruta.
Esta ruta en bucle permite al jugador echar un vistazo a la llave para que descubra el objetivo mientras recorre el primer segmento de la ruta.
Cuando hayas completado tu plan, empieza a diseñar el rompecabezas en el editor de niveles.
Una vez que hayas creado la ruta hasta la llave y nuevas formas de bloqueo, rellena el resto de la sala con trampas de fuego para oscurecer la ruta correcta.
Cambia los nombres de los objetos de nivel en el esquematizador para que quede claro qué trampas de fuego controla cada interruptor. Por ejemplo, si BP_Switch1 desactiva tres trampas, nómbralas BP_FireTrap_S1_0, BP_FireTrap_S1_1 y BP_FireTrap_S1_2. Cambia el nombre de las trampas de fuego adicionales a algo como BP_FireTrap_Extra para que no formen parte del rompecabezas.
Si quieres, puedes ayudar al jugador a salir cuando complete el rompecabezas añadiendo un último interruptor debajo de la llave que desactive algunas trampas en el camino.
Pon a prueba tu rompecabezas con frecuencia, prestando atención a las líneas de visión, los puntos de frustración y los posibles atajos. Recluta a un amigo para que te ayude; es posible que encuentren errores que no esperabas. Durante las pruebas, puede que te des cuenta de que tienes que hacer ajustes para que el jugador deje de saltarse partes del rompecabezas o disuadirle de ello.
Si descubres una vulnerabilidad, tienes dos opciones:
Reorganiza la ruta o el rompecabezas.
Añade más bloqueadores arquitectónicos.
Aumenta el daño de fuego para que desviarse de la ruta tenga peores consecuencias.
Abandonar un vulnerabilidad pero aumentar el coste da al jugador opciones y autonomía. Pueden elegir entre dedicar más tiempo a revelar la ruta segura o sacrificar sus PS para ir corriendo hacia la llave.
En el rompecabezas del nivel de muestra, hemos añadido algunos escombros debajo del arco de la llave para que el jugador pueda verla, pero no pueda saltar directamente a ella. También hemos escondido los interruptores no solo para crear algunas revelaciones gratificantes, sino también para evitar que el jugador se saltes esa parte de la ruta.
Añade pinchos en obstáculos pasados
Vamos a añadir pinchos a los rompecabezas anteriores para añadir consecuencias por las caídas
Empieza por el rompecabezas de la sala 1. En la primera plataforma móvil, no lo compliques demasiado para que, si el jugador se cae, solo tenga que volver a subir e intentarlo de nuevo. Cuando introduzcas una nueva mecánica, dale al jugador espacio para que aprenda en un lugar seguro y pueda centrarse en practicar.
Del mismo modo, en la sala inicial puedes añadir algunos pinchos en el foso que hay debajo de la primera llave. El jugador puede practicar saltando en las dos primeras plataformas para prepararse para el salto final (que es más arriesgado) sobre la llave. Ahora, agarrar la primera llave sin sufrir daños se vuelve un poco más emocionante.
Cuando el jugador haya comprendido los conceptos básicos y tenga algo de práctica moviendo bloques en plataformas y usando interruptores, es el momento de añadir consecuencias. Debajo de la segunda plataforma o del tercer botón, coloca algunas trampas de pinchos. Ahora has subido la tensión, ya que el jugador recibe daño si se cae, pero puede salir rápidamente de la trampa para minimizar ese daño y continuar.
Por último, para la última plataforma e interruptor, sigue aumentando el peligro. Cubre el área inferior con pinchos para que el jugador tenga que correr más lejos para salir de los pinchos y, por lo tanto, reciba más daño. Llegados a este punto, el jugador debería dominar más la mecánica y sentir que las consecuencias de sus errores son más justas, puesto que ya ha practicado.
Este diseño sigue esta estructura popular para presentar las mecánicas de jugabilidad a los jugadores:
Introducción: la primera plataforma enseña la mecánica del juego de forma segura.
Desarrollo: el segundo cubo y plataforma pone a prueba la habilidad creciente del jugador con un riesgo moderado.
Giro: la plataforma final aumenta el peligro y añade una nueva dirección de movimiento, convirtiendo la mecánica en un tenso desafío.
Tal y como aprendiste en la lección de diseño de la jugabilidad de la sección Rompecabezas: plataformas móviles, al potenciar las consecuencias en el rompecabezas se consigue equilibrar la equidad y la emoción.
Cambia el daño de una trampa
Puedes decidir si quieres cambiar el nivel de dificultad aumentando o disminuyendo el daño de un tipo de trampa. Puedes hacerlo de dos maneras:
En el esquematizador, busca «pincho» o «fuego» y selecciona todas las trampas de ese tipo. En el panel Detalles, cambia los ajustes de Configuración > Daño base como quieras. Con este método, también tendrías que acordarte de cambiar el daño base de cualquier nueva instancia de esa trampa que añadas a tu nivel. También puedes añadir nuevas instancias de trampas al nivel duplicando las existentes para evitar tener que editar cada nueva instancia.
O BIEN
Abre uno de tus blueprints de trampa hijo y ve a la pestaña Secuencia de comandos de construcción. No puedes editar variables heredadas en el panel My Blueprint, pero sí puedes establecer variables en el grafo. Después de los dos nodos Construction Script, conecta un nodo Set Base Damage. En el nodo, cambia el valor de Base Damage como quieras.
Para garantizar que tus objetos de jugabilidad sean predecibles para el jugador, garantiza que todas las trampas de un tipo inflijan el mismo daño.
En el nivel de muestra del tutorial, las trampas de fuego infligen 5 puntos de daño por segundo y las instancias de trampas con pinchos se han modificado para que inflijan 10 puntos de daño por segundo.
Prueba el nivel de muestra
Si prefieres usar contenido de la sala diseñado en esta parte del tutorial en lugar de crear uno propio, copia los fragmentos de abajo.
Bloqueo de la sala 2
Este fragmento de texto contiene el suelo y las paredes de la sala 2, así como las nuevas formas de bloqueo añadidas para crear el rompecabezas de la sala. En el esquematizador, todas las formas se encuentran en una carpeta llamada Sala2.
Begin Map
Begin Level
Begin Actor Class=/Script/Engine.TextRenderActor Name=TextRenderActor_19 Archetype="/Script/Engine.TextRenderActor'/Script/Engine.Default__TextRenderActor'" ExportPath="/Script/Engine.TextRenderActor'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19'"
Begin Object Class=/Script/Engine.TextRenderComponent Name="NewTextRenderComponent" Archetype="/Script/Engine.TextRenderComponent'/Script/Engine.Default__TextRenderActor:NewTextRenderComponent'" ExportPath="/Script/Engine.TextRenderComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19.NewTextRenderComponent'"
End Object
Begin Object Class=/Script/Engine.BillboardComponent Name="Sprite" Archetype="/Script/Engine.BillboardComponent'/Script/Engine.Default__TextRenderActor:Sprite'" ExportPath="/Script/Engine.BillboardComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19.Sprite'"
End Object
Begin Object Name="NewTextRenderComponent" ExportPath="/Script/Engine.TextRenderComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19.NewTextRenderComponent'"
Text=NSLOCTEXT("[3C535F7772EB3B3657484B5E2D5B925D]", "2347F80B407C68C27836E990A20143CF", "Room 2")
HorizontalAlignment=EHTA_Center
Para copiar todo el bloqueo de la sala 2, sigue estos pasos:
Elimina todo lo que haya en la sala 2 (o todo lo que haya al final del pasillo 2):
Usa el esquematizador para seleccionar el contenido existente de Sala 2: haz clic derecho en la carpeta
Sala2y selecciona Seleccionar > Hijos directos. Pulsa Supr.También puedes cambiar el visor a la vista ortogonal Superior para seleccionar y eliminar la sala existente manualmente.
Haz clic en Copiar el fragmento completo.
En Unreal Editor, asegúrate de que el visor sea el panel activo (haz clic en cualquier parte del visor o del esquematizador y pulsa Esc) y, a continuación, pulsa Ctrl + V.
Tu nivel y el esquematizador deberían tener un aspecto similar al siguiente:
Interruptores, trampas y llave de la sala 2
Este fragmento de texto contiene los interruptores, las trampas y la llave roja del rompecabezas. En el esquematizador, todos los objetos están en una carpeta llamada Sala2.
Para copiar instancias de blueprint entre proyectos, los recursos del blueprint padre deben ser completamente idénticos y tener los mismos nombres de archivo y ubicaciones. Si has cambiado los componentes, los nombres de las variables o las propiedades del blueprint en tu proyecto, es posible que el fragmento no se copie correctamente y tengas que configurar estos objetos del nivel manualmente.
Begin Map
Begin Level
Begin Actor Class=/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C Name=BP_FireTrap_C_261 Archetype="/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.Default__BP_TrapFire_C'" ExportPath="/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261'"
Begin Object Class=/Script/Engine.SceneComponent Name="DefaultSceneRoot" Archetype="/Script/Engine.SceneComponent'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C:ICH-DefaultSceneRoot_GEN_VARIABLE'" ExportPath="/Script/Engine.SceneComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.DefaultSceneRoot'"
End Object
Begin Object Class=/Script/Engine.StaticMeshComponent Name="TrapBase" Archetype="/Script/Engine.StaticMeshComponent'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C:TrapBase_GEN_VARIABLE'" ExportPath="/Script/Engine.StaticMeshComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.TrapBase'"
End Object
Begin Object Class=/Script/Engine.BoxComponent Name="TrapTrigger" Archetype="/Script/Engine.BoxComponent'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C:TrapTrigger_GEN_VARIABLE'" ExportPath="/Script/Engine.BoxComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.TrapTrigger'"
End Object
Begin Object Name="DefaultSceneRoot" ExportPath="/Script/Engine.SceneComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.DefaultSceneRoot'"
Para configurar las piezas del blueprint del rompecabezas, sigue estos pasos:
Haz clic en Copiar el fragmento completo.
En Unreal Editor, asegúrate de que el visor o el esquematizador sean el panel activo y pulsa Ctrl + V.
Comprueba las propiedades de configuración de cada interruptor y, si es necesario, vuelve a conectar cada interruptor a sus trampas de fuego:
En el esquematizador, en la carpeta
Sala2, haz clic enBP_Switch4.En la sección Configuración del panel Detalles, amplía la lista de objetos de interacción.
Para cada elemento de la lista, haz clic en el desplegable, busca
S4y selecciona una de las trampas de fuego con la etiquetaS4.Repite estos pasos para cada interruptor:
BP_Switch5activaBP_FireTrap_S5_0-7BP_Switch6activaBP_FireTrap_S6_0-3BP_Switch7activaBP_FireTrap_S7_0-4BP_Switch8activaBP_FireTrap_S8_0-3BP_Switch9, debajo de la llave, activaBP_FireTrap_S9_0-4
Tu nivel y el esquematizador deberían tener un aspecto similar al siguiente:
Siguiente
A continuación, aprenderás a añadir otro peligro popular a tu juego: ¡los PNJ enemigos! Obtén más información sobre cómo crear un personaje enemigo de IA y a añadir una malla de navegación a tu nivel para que los enemigos puedan encontrar al jugador y hacerle daño.