Unreal Engine: Creación de un Sistema de Diálogos Ramificados con Data Tables y Blueprint
Este tutorial te guiará en la creación de un robusto sistema de diálogos ramificados para tus juegos en Unreal Engine 5. Utilizaremos Data Tables para gestionar el contenido de los diálogos y Blueprints para la lógica de visualización e interacción. Prepárate para dar vida a tus personajes y enriquecer la narrativa de tu juego.
🚀 Introducción al Sistema de Diálogos Ramificados en Unreal Engine
Los sistemas de diálogo son el corazón narrativo de muchos videojuegos, permitiendo a los jugadores interactuar con personajes, tomar decisiones que afectan la historia y sumergirse en el mundo del juego. Un sistema de diálogos ramificados va un paso más allá, ofreciendo múltiples caminos y consecuencias basadas en las elecciones del jugador, lo que aumenta la rejugabilidad y la profundidad narrativa.
En este tutorial, construiremos un sistema de diálogo flexible y escalable en Unreal Engine 5 utilizando dos herramientas poderosas: Data Tables para la organización de los datos de diálogo y Blueprints para la lógica visual y la interfaz de usuario. Al final, tendrás un sistema funcional que podrás adaptar y expandir a tus propios proyectos.
¿Por qué Data Tables y Blueprints?
- Data Tables: Son ideales para almacenar grandes cantidades de datos estructurados de manera eficiente. Nos permiten separar el contenido del diálogo (texto, personaje, opciones, etc.) de la lógica del juego, facilitando la edición por parte de escritores o diseñadores sin necesidad de tocar código.
- Blueprints: Proporcionan un entorno visual para crear la lógica del juego, lo que es perfecto para manejar la secuencia de diálogos, mostrar opciones al jugador, y procesar sus elecciones. Es una solución rápida y potente para la mayoría de las necesidades de juego.
🛠️ Configuración Inicial del Proyecto
Antes de sumergirnos en la creación del sistema, necesitamos configurar nuestro proyecto.
1. Creación de una Estructura de Datos para el Diálogo (Struct)
Primero, necesitamos definir cómo se verá una línea de diálogo en nuestro juego. Para esto, crearemos una Structure en Blueprint.
- En el Content Browser, haz clic derecho y selecciona
Blueprints>Structure. - Nómbrala
ST_DialogueNode. - Abre
ST_DialogueNodey añade las siguientes variables:NodeID(Type:Name): Un identificador único para cada nodo de diálogo. Será nuestra clave principal.CharacterName(Type:Text): El nombre del personaje que está hablando.DialogueText(Type:Text): El texto principal de la línea de diálogo.Choices(Type:ArrayofST_DialogueChoice): Un array que contendrá las opciones que el jugador puede seleccionar. (Necesitaremos crearST_DialogueChoiceprimero).DefaultNextNodeID(Type:Name): ElNodeIDdel siguiente diálogo si no hay opciones o si no se elige ninguna.IsEndNode(Type:Boolean): Indica si este nodo finaliza la secuencia de diálogo.
Ahora, creemos la estructura para las opciones de diálogo.
- En el Content Browser, haz clic derecho y selecciona
Blueprints>Structure. - Nómbrala
ST_DialogueChoice. - Abre
ST_DialogueChoicey añade las siguientes variables:ChoiceText(Type:Text): El texto que se mostrará al jugador para esta opción.NextNodeID(Type:Name): ElNodeIDdel diálogo al que se pasa si el jugador elige esta opción.
2. Creación de la Tabla de Datos (Data Table)
Con nuestras estructuras definidas, podemos crear la Data Table que almacenará todos nuestros diálogos.
- En el Content Browser, haz clic derecho y selecciona
Miscellaneous>Data Table. - Se te pedirá que elijas una Row Structure. Selecciona
ST_DialogueNode. - Nómbrala
DT_Dialogue. - Abre
DT_Dialogue. Aquí es donde introduciremos nuestras líneas de diálogo. Por ahora, deja un par de filas de ejemplo para empezar.-
Haz clic en
Addpara añadir una nueva fila. -
Row Name:Intro1 -
CharacterName:Narrador -
DialogueText:Te encuentras en una encrucijada. ¿Qué camino tomas? -
Choices: (Añade dos elementos aquí)- Choice 1:
ChoiceText:Ir a la izquierda,NextNodeID:PathLeft1 - Choice 2:
ChoiceText:Ir a la derecha,NextNodeID:PathRight1
- Choice 1:
-
DefaultNextNodeID: (Déjalo vacío por ahora) -
IsEndNode:False -
Añade otra fila:
Row Name:PathLeft1CharacterName:GuardiaDialogueText:¡Alto! ¿Quién eres?Choices: (Añade un elemento)- Choice 1:
ChoiceText:Soy un aventurero.,NextNodeID:GuardTalk1
- Choice 1:
DefaultNextNodeID: (Déjalo vacío)IsEndNode:False
-
Añade una tercera fila:
Row Name:PathRight1CharacterName:MercaderDialogueText:¡Bienvenido, viajero! ¿Buscas algo en particular?Choices: (Añade un elemento)- Choice 1:
ChoiceText:Solo miro, gracias.,NextNodeID:EndDialogue
- Choice 1:
DefaultNextNodeID: (Déjalo vacío)IsEndNode:False
-
Añade una cuarta fila:
Row Name:GuardTalk1CharacterName:GuardiaDialogueText:Pasa, pero ten cuidado.Choices: (vacío)DefaultNextNodeID:EndDialogueIsEndNode:False
-
Añade la fila final:
Row Name:EndDialogueCharacterName:(Silencio)DialogueText:Fin del diálogo.Choices: (vacío)DefaultNextNodeID: (vacío)IsEndNode:True
-
Guardar DT_Dialogue.
🎨 Creación de la Interfaz de Usuario (UMG)
Necesitamos una interfaz para mostrar el diálogo y las opciones al jugador.
1. Widget de Línea de Diálogo Individual (para opciones)
Este widget representará cada opción de diálogo que el jugador puede seleccionar.
- En el Content Browser, haz clic derecho y selecciona
User Interface>Widget Blueprint>UserWidget. - Nómbrala
WB_DialogueChoiceButton. - Ábrela y arrastra un
Buttondesde la paleta alCanvas Panel. - Dentro del
Button, arrastra unText Block. - Renombra el
Text BlockaChoiceText_TextBlocky marcaIs Variableen los detalles. - Selecciona el
Buttony enDetails>Events, haz clic en+junto aOnClicked.
En el Graph de WB_DialogueChoiceButton:
- Crea una variable
NextNodeID(Type:Name) y marcaExpose on Spawn. - Crea un
Event DispatcherllamadoOnChoiceSelectedcon una entradaNextNodeID(Type:Name).
En el evento OnClicked del botón:
CallelEvent DispatcherOnChoiceSelected, pasando la variableNextNodeID.
2. Widget Principal del Sistema de Diálogo
Este será el widget principal que contendrá el texto del diálogo, el nombre del personaje y los botones de opción.
- En el Content Browser, haz clic derecho y selecciona
User Interface>Widget Blueprint>UserWidget. - Nómbrala
WB_DialogueSystem. - Ábrela y en el
Designer, añade los siguientes elementos (puedes usar unVertical BoxoBordercomo contenedores):Text Blockpara el nombre del personaje. Renómbralo aCharacterName_TextBlocky marcaIs Variable.Text Blockpara el texto del diálogo. Renómbralo aDialogueText_TextBlocky marcaIs Variable.Vertical Boxpara contener los botones de opción. Renómbralo aChoicesVerticalBoxy marcaIs Variable.- Un
Button(opcional) para avanzar el diálogo si no hay opciones. Renómbralo aContinueButtony marcaIs Variable.
En el Graph de WB_DialogueSystem:
-
Crea una función
ShowDialogueNodeque tome unST_DialogueNodecomo entrada.- Esta función actualizará
CharacterName_TextBlockyDialogueText_TextBlock. - Borrará todos los hijos de
ChoicesVerticalBox. - Para cada
Choiceen el arrayChoicesdeST_DialogueNode:Create WidgetdeWB_DialogueChoiceButton.SetelNextNodeIDdel botón recién creado.Set TextdelChoiceText_TextBlockdel botón.Add ChildalChoicesVerticalBox.Bind Event to OnChoiceSelecteddel botón para llamar a un evento personalizado, por ejemplo,OnChoiceMade.
- Si no hay opciones (
Choicesestá vacío) o siIsEndNodeesFalse:- Mostrar
ContinueButton. Set VisibilitydelChoicesVerticalBoxaHidden.
- Mostrar
- Si hay opciones:
- Ocultar
ContinueButton. Set VisibilitydelChoicesVerticalBoxaVisible.
- Ocultar
- Esta función actualizará
-
Crea un
Event DispatcherllamadoOnDialogueNodeRequestedcon una entradaNextNodeID(Type:Name). -
Crea un
Custom EventOnChoiceMadeque reciba unNextNodeID(Type:Name).CallelEvent DispatcherOnDialogueNodeRequestedcon elNextNodeIDrecibido.
-
En el evento
OnClickeddeContinueButton:CallelEvent DispatcherOnDialogueNodeRequestedcon elDefaultNextNodeIDdel nodo actual (que deberemos pasar como variable al widget o almacenar).
🧠 Lógica Principal del Diálogo (Blueprint del Juego)
Necesitamos un lugar centralizado para gestionar el flujo del diálogo. Un Player Controller, Game Mode o un Actor Component son buenas opciones. Para este tutorial, usaremos el Player Controller por simplicidad.
1. Blueprint del Player Controller (o Actor Component)
- Abre tu
Player Controller(o crea un nuevoBlueprint Actor ComponentllamadoBP_DialogueManager). - Añade una variable
CurrentDialogueNodeID(Type:Name). Inicialízala a un valorNoneo elNodeIDinicial de tu diálogo (Intro1). - Añade una variable
DialogueWidget(Type:WB_DialogueSystem Object Reference).
2. Funciones de Carga y Visualización del Diálogo
En tu Player Controller (o BP_DialogueManager):
-
Crea una función
StartDialogueque tome unStartingNodeID(Type:Name) como entrada.SetCurrentDialogueNodeIDalStartingNodeID.Create WidgetdeWB_DialogueSystemyAdd to Viewport.Setla variableDialogueWidget.Bind Event to OnDialogueNodeRequesteddeDialogueWidgetpara llamar a un evento personalizadoHandleDialogueNodeRequest.- Llama a la función
DisplayCurrentDialogueNode.
-
Crea una función
DisplayCurrentDialogueNode.Get Data Table RowdeDT_DialogueusandoCurrentDialogueNodeIDcomoRow Name.- Si la fila es válida (Has
Validoutput):- Llama a la función
ShowDialogueNodeenDialogueWidget, pasando la estructura de la fila. - Si
IsEndNodede la fila esTrue:Delaypor unos segundos.Remove from ParentdeDialogueWidget.SetDialogueWidgetaNone.SetCurrentDialogueNodeIDaNone.- (Opcional)
Unbindel eventoOnDialogueNodeRequested.
- Llama a la función
- Si la fila no es válida:
Print Stringcon un mensaje de error.- Terminar diálogo (similar a
IsEndNode).
-
Crea un
Custom EventHandleDialogueNodeRequestque reciba unNextNodeID(Type:Name).SetCurrentDialogueNodeIDalNextNodeIDrecibido.- Llama a la función
DisplayCurrentDialogueNode.
3. Activación del Diálogo
Para probar nuestro sistema, podemos activarlo desde un Actor en el nivel.
- Crea un nuevo
Blueprint ActorllamadoBP_DialogueTrigger. - Añade un
Box CollisionaBP_DialogueTrigger. - En el
Event GraphdeBP_DialogueTrigger:- En el evento
OnComponentBeginOverlapdelBox Collision:Cast TotuPlayer Character.- Si el
Castes exitoso:Get Player Controller.Cast TotuPlayer Controller(el que contiene la lógica de diálogo).- Si el
Castes exitoso:- Llama a la función
StartDialogueen elPlayer Controller, pasandoIntro1comoStartingNodeID. - (Opcional)
Destroy Actorpara que el diálogo no se active múltiples veces.
- Llama a la función
- En el evento
Coloca una instancia de BP_DialogueTrigger en tu nivel y prueba a que tu personaje colisione con él.
✨ Mejoras Adicionales y Personalización
Este es un sistema básico pero robusto. Aquí hay ideas para expandirlo:
1. Efectos de Sonido y Animaciones
- Sonido: Añade una variable
SoundCueaST_DialogueNodey reprodúcelo cuando se muestre el nodo. - Animaciones: Podrías incluir un
AnimationoMontagea reproducir para el personaje hablante, o animar el widget de diálogo para que aparezca/desaparezca suavemente.
2. Lógica Condicional en las Opciones
- Añade variables a
ST_DialogueChoicepara almacenar condiciones (ej.RequiredItem,RequiredStatValue). - En
WB_DialogueSystem, antes de añadir un botón de opción, verifica si el jugador cumple las condiciones. Si no, deshabilita el botón o lo oculta.
3. Eventos al Finalizar un Diálogo
- Añade un
Event Dispatcheren elPlayer Controller(oBP_DialogueManager) llamadoOnDialogueFinished. CallesteDispatchercuando el diálogo llegue a unIsEndNode.- Otros sistemas (misiones, IA) pueden
Binda este evento para reaccionar cuando un diálogo termina.
4. Nombres y Avatares de Personajes Dinámicos
- Puedes tener una
DataTableseparada para los datos de los personajes (nombre completo, textura del avatar, color de texto, etc.) y usar elCharacterNamedeST_DialogueNodecomoRow Namepara obtener esos datos.
5. Diálogos Secuenciales sin Elecciones
- Si un nodo no tiene opciones, automáticamente debería avanzar al
DefaultNextNodeID(que ya hemos implementado con elContinueButton). SiDefaultNextNodeIDtambién está vacío, el diálogo termina o espera una interacción manual (como en elIsEndNode).
📝 Resumen del Flujo de Trabajo
Conclusión 🎉
Has aprendido a construir un sistema de diálogos ramificados funcional y extensible en Unreal Engine 5 utilizando Data Tables y Blueprints. Este enfoque separa el contenido de la lógica, haciendo que el sistema sea fácil de mantener, escalar y personalizar.
La versatilidad de las Data Tables, combinada con la potencia visual de Blueprints, te permite crear narrativas ricas y envolventes para tus juegos. Experimenta con las mejoras sugeridas y adapta este sistema a las necesidades específicas de tu proyecto.
¡Ahora tienes las herramientas para dar voz a tus personajes y permitir que los jugadores tomen decisiones significativas en tu mundo de juego!
Tutoriales relacionados
- Dominando el Sistema de Animación en Unreal Engine 5: Desde Retargeting hasta Blend Spacesintermediate20 min
- Unreal Engine: Implementando IA Básica con Behaviour Trees y EQS para Enemigosintermediate15 min
- Unreal Engine: Creando un Sistema de Inventario Dinámico con UMG y C++intermediate25 min
- Unreal Engine: Creando Interactividad con el Sistema de Interacciones Basado en Componentesintermediate15 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!