142 lines
7.0 KiB
Markdown
142 lines
7.0 KiB
Markdown
# Proyecto UI U-Tad
|
|
|
|
**[Read in English](README.md)** | **Español**
|
|
|
|
---
|
|
|
|
## Implementación del Sistema de Árbol de Habilidades
|
|
|
|
### Resumen
|
|
Un sistema completo de árbol de habilidades con progresión basada en nodos, validación de prerrequisitos, líneas de conexión visuales y configuración orientada a datos.
|
|
|
|

|
|
|
|
---
|
|
|
|
## Arquitectura: Decisión de Blueprint
|
|
|
|
### Implementación en Blueprint
|
|
**Componentes:** `WBP_SkillTree`, `WBP_SkillNode`, `WBP_SkillNodeTooltip`
|
|
|
|
**Justificación:**
|
|
- **Velocidad de iteración**: El diseño y estilización de UI requiere iteración visual rápida
|
|
- **Amigable para diseñadores**: Artistas/diseñadores pueden modificar la UI sin conocimientos de C++
|
|
|
|

|
|
|
|
---
|
|
|
|
## Sistemas Principales
|
|
|
|
### 1. Capa de Datos (`SkillTreeTypes.h`)
|
|
**Estructuras:**
|
|
- `FSkillNodeData`: Fila de definición de habilidad para la tabla de datos (nombre, coste, prerrequisitos, efectos, bandera de inicio)
|
|
- `FSkillNodeRuntime`: Envoltorio de estado en tiempo de ejecución
|
|
- `ESkillNodeState`: Enum de estado (Bloqueado, Disponible, Seleccionado, Comprado)
|
|
|
|
**Decisión**: El diseño basado en Data Table permite a no programadores configurar habilidades sin recompilar.
|
|
|
|

|
|
|
|
### 2. Capa de Lógica (`SkillTreeComponent`)
|
|
**Responsabilidades:**
|
|
- Inicialización del árbol de habilidades desde DataTable
|
|
- Gestión de estado (prerrequisitos, comprobaciones de asequibilidad)
|
|
- Validación de selección y confirmación de compra
|
|
- Auto-compra de habilidades iniciales
|
|
- Gestión de puntos de habilidad
|
|
- Ganchos de aplicación de efectos
|
|
|
|
**Características Clave:**
|
|
- **Ordenación por orden de compra**: Asegura que los prerrequisitos se compren antes que los dependientes
|
|
- **Deselección en cascada**: Eliminar un prerrequisito deselecciona las habilidades dependientes
|
|
- **Habilidades iniciales**: Marcadas en DataTable, auto-compradas en init, preservadas en reset
|
|
- **Agregación de estadísticas**: Proporciona funciones `GetTotal[Stat]Bonus()` para sumar bonificaciones de todas las habilidades compradas
|
|
|
|
### 3. Capa de Integración de Estadísticas (`CharacterStatsComponent`)
|
|
**Responsabilidades:**
|
|
- Cálculo automático de estadísticas desde habilidades compradas
|
|
- Gestión de estadísticas del personaje (Salud, Daño, Velocidad)
|
|
- Actualizaciones en tiempo real cuando se compran habilidades
|
|
- Integración con velocidad de movimiento
|
|
|
|
**Cómo funciona:**
|
|
- Encuentra SkillTreeComponent en el mismo actor en BeginPlay
|
|
- Escucha el evento `OnSkillPurchased`
|
|
- Itera todas las habilidades compradas, suma bonificaciones planas + porcentuales
|
|
- Aplica fórmula: `StatFinal = Base + BonusPlano + (Base * BonusPorcentual / 100)`
|
|
- Auto-actualiza la velocidad de CharacterMovementComponent
|
|
- Emite eventos de cambio de estadísticas para actualizaciones de UI
|
|
|
|
**Decisión**: Un componente de estadísticas separado mantiene las responsabilidades separadas - SkillTreeComponent maneja la progresión, CharacterStatsComponent maneja la aplicación de estadísticas. Hace ambos reutilizables independientemente.
|
|
|
|
### 4. Capa de Visualización (`SkillTreeConnectionsWidget`)
|
|
**Responsabilidades:**
|
|
- Dibujado automático de líneas entre nodos prerrequisito (¡Solo necesitas colocar los nodos en la UI!)
|
|
- Coloreado dinámico de líneas basado en estados de habilidades
|
|
- Refresco basado en eventos cuando cambian los estados
|
|
|
|
**Enfoque Técnico:**
|
|
- **Búsqueda genérica**: Funciona con cualquier jerarquía de widgets para que diseñadores/artistas no estén limitados al crear el widget del árbol de habilidades (Canvas, Overlay, Grid)
|
|
- **Override de NativePaint**: Renderizado directo con Slate para rendimiento
|
|
- **Binding de delegados**: Se refresca automáticamente cuando cambian los estados de las habilidades
|
|
|
|
**Decisión**: Un único widget auto-contenido elimina la gestión manual de líneas y complejidad de Blueprint.
|
|
|
|
<p align="center">
|
|
<img src="Docs/Images/Lines_1.png" alt="Lines 1" width="45%"/>
|
|
<img src="Docs/Images/Lines_2.png" alt="Lines 1" width="45%"/>
|
|
</p>
|
|
|
|
### 5. Capa de UI (Blueprints)
|
|
**WBP_SkillNode & WBP_SkillNodeTooltip:**
|
|
- Muestra icono de habilidad, estado, coste
|
|
- Maneja eventos de clic (seleccionar/deseleccionar)
|
|
- Almacena SkillID para búsqueda en tiempo de ejecución
|
|
- Soporte de tooltip personalizado para mostrar detalles de habilidad
|
|
- Actualizaciones de estado en tiempo real mediante binding de eventos permiten feedback visual instantáneo
|
|
|
|
**WBP_SkillTree:**
|
|
- Contiene nodos de habilidad colocados manualmente
|
|
- Referencia a SkillTreeComponent
|
|
- Aloja SkillTreeConnectionsWidget que dibuja líneas entre nodos automáticamente
|
|
- Se vincula a eventos del componente para actualizaciones de UI
|
|
|
|
**Decisión**: La colocación manual de nodos permite diseños personalizados (lineal, radial, ramificado) según preferencia del diseñador.
|
|
|
|
---
|
|
|
|
## Decisiones Clave de Diseño
|
|
|
|
### 1. Prerrequisitos de habilidades en DataTable
|
|
**Alternativa**: Hard-coded en C++ o referencias a DataAssets
|
|
**Elegido**: Array en DataTable
|
|
**Razón**: Los diseñadores pueden modificar dependencias de habilidades sin intervención del programador y sin recompilar
|
|
|
|
### 2. Componente vs Subsistema
|
|
**Alternativa**: Game Instance Subsystem
|
|
**Elegido**: Actor Component
|
|
**Razón**: Soporta múltiples árboles de habilidades por jugador (ej., árbol de combate, árbol de crafteo) y más fácil integración con guardar/cargar
|
|
|
|
### 3. Widget de Conexiones Único
|
|
**Alternativa**: Widgets de línea individuales por conexión con gestión manual
|
|
**Elegido**: Un widget dibuja todas las líneas automáticamente
|
|
**Razón**: Elimina gestión de arrays, mejor rendimiento, manejo automático de coordenadas
|
|
|
|
### 4. Componente de Estadísticas Separado
|
|
**Alternativa**: Aplicar estadísticas directamente en SkillTreeComponent
|
|
**Elegido**: CharacterStatsComponent separado
|
|
**Razón**: Separación de responsabilidades - SkillTreeComponent es reutilizable para cualquier sistema de progresión, CharacterStatsComponent específicamente maneja estadísticas de personaje. Permite árboles de habilidades sin bonificaciones de stats, o stats sin árboles de habilidades.
|
|
|
|
---
|
|
|
|
## Aspectos Técnicos Destacados
|
|
|
|
- **Arquitectura basada en eventos**: El componente emite cambios de estado, la UI responde automáticamente
|
|
- **Validación de máquina de estados**: Previene transiciones inválidas (ej., no se pueden seleccionar habilidades bloqueadas)
|
|
- **Aplicación automática de estadísticas**: CharacterStatsComponent escucha compras de habilidades, recalcula estadísticas, las aplica al personaje
|
|
- **Renderizado consciente de geometría**: Las líneas se adaptan a cualquier sistema de posicionamiento de widgets
|
|
- **Configuración orientada a datos**: Cero cambios de código y no necesita compilar para nuevas habilidades o diseños de árbol
|
|
- **Funcionalidad de reinicio**: Reembolsa habilidades no iniciales, mantiene puntos de inicio
|
|
- **Diseño modular**: Progresión de habilidades, estadísticas y visualización son independientes
|