Tutorial de Scripting Visual (Ladrillos Lógicos)
Creando los Botones de Plataforma
Lesson 9 of 10 • 10 XP
Keep your place in this quest
Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.
En esta lección, terminaremos el sistema que comenzamos en la lección anterior creando los botones que se conectarán a la lógica de la plataforma y completarán la interacción entre ambos sistemas.
Durante este proceso, exploraremos varios conceptos importantes en el sistema lógico visual de Cave. Aprenderás a detectar colisiones usando un Cuerpo Rígido, usar el nodo Delay para controlar cuándo ocurren las acciones a lo largo del tiempo, cambiar el color de una Entidad durante la jugabilidad, y también practicarás crear y usar funciones para mantener tus Ladrillos Lógicos organizados y reutilizables.
Al final de esta lección, tendremos un sistema completo donde los botones pueden ser activados por el Jugador y se comunican correctamente con la plataforma creada anteriormente.
1. Creando el Botón
Para comenzar a crear el botón, primero crea una nueva Plantilla de Entidad.
Luego, renombra la Entidad según su propósito, configura la Malla que se usará como su representación visual, y agrega los componentes de física necesarios para que interactúe correctamente dentro del juego.
Después de eso, crea un nuevo Ladrillo Lógico y conéctalo a la Entidad del botón.
Este proceso es muy similar a lo que hicimos anteriormente al crear la plataforma, así que también es una buena oportunidad para practicar los conceptos que ya aprendiste.
Al final de este paso, tendremos la estructura básica del botón lista para recibir su lógica de activación.

Ahora, hay un paso muy importante: no podemos olvidar agregar la etiqueta button a la Entidad del botón.
Si recuerdas, en la lección anterior ya preparamos la lógica de la plataforma para contar automáticamente cuántos botones existen en la escena usando esta etiqueta exacta.
Por eso, la etiqueta necesita ser creada y asignada al botón usando el mismo nombre que se utilizó en la lógica de la plataforma.
Si el nombre de la etiqueta es diferente, incluso por un pequeño detalle, la plataforma no podrá encontrar los botones correctamente y el conteo no funcionará como se espera.
Así que antes de continuar, asegúrate de crear la etiqueta button y agregarla a la Entidad del botón.

Ahora, también agreguemos una propiedad a la Entidad del botón.
Usamos la etiqueta button para identificar el botón dentro del mapa, pero usaremos una propiedad para controlar parte de su comportamiento.
Crea una nueva propiedad llamada Tiempo Activo, de tipo Float.
Esta propiedad almacenará cuánto tiempo debe permanecer activo el botón antes de regresar automáticamente al estado inactivo.
Esto hace que el sistema sea más flexible porque cada botón puede tener un tiempo de activación diferente. Por ejemplo, un botón puede permanecer activo durante 3 segundos, mientras que otro botón puede permanecer activo durante 10 segundos, sin cambiar el Ladrillo Lógico en sí.

2. Creando la Lógica del Botón
Ahora que nuestra Entidad está lista, con la etiqueta y la propiedad configuradas, comencemos a crear el comportamiento del botón.
El primer paso es detectar la colisión entre la Entidad del botón y el Jugador, para que podamos activarlo cuando el Jugador lo toque.
Sin embargo, antes de implementar esta lógica, necesitamos considerar un detalle importante: solo queremos que el botón sea activado cuando esté actualmente inactivo.
Dado que el botón tendrá dos estados diferentes, activo e inactivo, necesitamos una forma de almacenar qué estado se está utilizando actualmente.
Para hacer esto, crea una nueva propiedad en el Ladrillo Lógico del botón llamada Botón Activo, de tipo Boolean.
Esta propiedad almacenará el estado actual del botón, indicando si está activo o no. Usaremos este valor en los próximos pasos para controlar todo el comportamiento del botón.

Ahora podemos comenzar a construir la lógica visual.
En On Update, revisaremos constantemente si el botón está activo o inactivo usando la propiedad Botón Activo que acabamos de crear.
Para hacer eso, obtén su valor usando Get Active Button y usa un nodo If para verificar su estado.
Si la condición es Falsa, significa que el botón está inactivo y puede ser activado. En este caso, detectaremos la colisión entre el botón y el Jugador.
Para hacer esto, agrega un nodo Collided With.
Este nodo necesita un Componente de Cuerpo Rígido, así que obtén la Entidad del botón y, desde ella, obtén el Componente de Cuerpo Rígido que agregamos al configurar la física.
También necesitamos decirle al nodo qué objeto queremos detectar. Para eso, agrega una etiqueta player al personaje y pasa esta etiqueta a Collided With.
De esta manera, la colisión solo se considerará válida cuando el botón colisione con el Jugador.
Con esta estructura, el botón solo puede ser activado cuando está inactivo y cuando el Jugador realmente colisiona con él.

Ahora que tenemos ambos caminos definidos, vamos primero a implementar la lógica para cuando el botón está activo.
Después de eso, crearemos el comportamiento responsable de activarlo.
Para hacer esto, sigue la condición True del nodo If que verifica si el botón está activo o no.
En este flujo, utilizaremos la propiedad Tiempo Activo que creamos en la Entidad del botón para controlar cuánto tiempo debe permanecer activo el botón.
Primero, obtén la Entidad del botón y accede a sus propiedades a través del nodo Get Properties.
Luego usa Get Property, conectando el diccionario devuelto previamente y usando Tiempo Activo como la Key.
Dado que esta propiedad es un Float, cambia el tipo de salida de Get Property a Float, asegurándote de que podamos usar este valor correctamente en la siguiente parte de la lógica.

Ahora la salida de Get Property devuelve el valor de la propiedad Tiempo Activo, que define cuánto tiempo debe permanecer activo el botón.
A continuación, agrega un nodo Delay y usa este valor como duración.
De esta manera, el tiempo de espera se controla directamente por la propiedad de la Entidad, permitiendo que diferentes botones tengan diferentes tiempos de activación sin cambiar la lógica.
Después de que el Delay finalice, usa Set Active Button y establece su valor en False.
Con esto, el botón regresa automáticamente al estado inactivo después del tiempo especificado en su propiedad.

Muy bien. Ahora sigamos el otro camino y creamos el comportamiento responsable de activar el botón.
La salida del nodo Collided With devuelve un valor Bool.
Cuando este valor es True, significa que el botón colisionó con el Jugador.
En ese momento, podemos simplemente usar Set Active Button y establecer su valor en True.
Al hacer esto, el botón entra en el estado activo y comienza automáticamente a usar la lógica activa que creamos previamente, la cual lo mantiene activo durante un cierto tiempo y luego lo desactiva nuevamente.
Con esto, creamos un ciclo completo de comportamiento:
- cuando el Jugador colisiona con el botón, se activa
- después del tiempo definido en Tiempo Activo, se desactiva
- después de eso, puede ser activado nuevamente por otra colisión
Aunque esta lógica es simple, ya le da al botón dos estados diferentes y será la base para las próximas funciones que vamos a agregar.

Todo está funcionando, pero aún falta una pieza importante.
A pesar de que la lógica de activación y desactivación del botón ya funciona correctamente, nuestra plataforma aún no sabe cuándo se activa un botón.
Esto es exactamente donde la propiedad Conteo de Botones que creamos anteriormente en la Escena se vuelve importante.
Si recuerdas, en la lógica de la plataforma definimos que la plataforma solo debe ser eliminada cuando el valor de esta propiedad se vuelve igual al total de botones en el mapa.
En otras palabras, la plataforma ya está lista para reaccionar, pero hasta ahora ningún botón está cambiando este valor.
Lo que necesitamos hacer ahora es permitir que los botones modifiquen directamente la propiedad Conteo de Botones de la Escena cada vez que sean activados y desactivados.
Esta es una gran oportunidad para practicar otra característica muy importante de Ladrillos Lógicos en Cave: crear funciones.
En lugar de repetir la misma lógica múltiples veces, encapsularemos este comportamiento en funciones reutilizables, manteniendo nuestro Gráfico más organizado, más fácil de entender y más fácil de mantener.
Dado que la propiedad Conteo de Botones se almacena en la Escena, primero debemos acceder a ella.
Para hacer esto, obtén la Escena usando Get Scene, y luego usa Get Properties.

3. Creando la Función que Controla las Propiedades de la Escena
A partir de estos nodos, crearemos una función.
Para hacer esto, selecciona los nodos involucrados, haz clic derecho y elige Promote Selection to Function.

Luego renombra la nueva función a un nombre claro y descriptivo que represente su propósito dentro de la lógica del proyecto.
En este caso, utilizaremos el nombre Set Scene Property.

Ahora estructuremos cómo funcionará la función Set Scene Property.
Primero, pasa el diccionario de propiedades de la Escena al nodo Get Property. Este diccionario proviene del flujo de Get Scene → Get Properties.
Luego, cambia la salida de Get Property a Int, asegurándote de que estamos trabajando con valores enteros.
En Function Inputs, crea dos nuevos parámetros para esta función:
- Prop Name, de tipo String
- Value, de tipo Int
El parámetro Prop Name se utilizará como la Clave en Get Property, permitiendo que la función acceda a la propiedad deseada dentro del diccionario de propiedades de la Escena.
Luego actualizaremos esta propiedad utilizando Set Property.
Para hacer eso, obtiene el valor actual de la propiedad, agrega la entrada Value a él y escribe el resultado de nuevo en la misma propiedad.
Pasamos el diccionario de propiedades de la Escena nuevamente y usamos Prop Name como la clave.
Esto crea una función genérica y reutilizable que puede modificar las propiedades de la Escena de una manera simple y organizada.
En lugar de solo establecer un valor exacto, esta función funciona como un sistema de incremento: agrega el Value recibido al valor actual de la propiedad de la Escena.

Con esta función lista, ya no necesitamos mantener toda esa cadena de nodos directamente en el Grafo principal.
Ahora, en lugar de repetir toda la lógica, simplemente llamamos a la función justo después de establecer Active Button a True.
Esto significa que en el momento en que se activa el botón, le decimos inmediatamente a la lógica de la plataforma que se presionó un botón más.
Para hacer esto, pasa el nombre de la propiedad Button Count, que es la propiedad almacenada en la Escena, y envía el valor 1 como el incremento.
La función agregará automáticamente +1 al valor actual de esa propiedad.
De esta manera, cualquier botón activado actualiza directamente el progreso global del sistema, sin duplicar la lógica.
También nos da más flexibilidad para cambiar las propiedades de la Escena en el futuro reutilizando esta misma función.

Para mostrar cuán simple y flexible es esto, volvamos a la lógica del botón activo.
Justo después de que termina el tiempo de activación y establecemos Active Button a False, llamaremos a Set Scene Property nuevamente.
El parámetro Prop Name será Button Count, usando la misma propiedad de la Escena.
Pero esta vez, el parámetro Value será -1.
Dado que nuestra función agrega el valor recibido al valor actual de la propiedad de la Escena, pasar un número negativo resta automáticamente 1 del Button Count actual.

De esta manera, cada vez que un botón se desactiva, el sistema también actualiza correctamente el progreso global, manteniendo la lógica de la plataforma sincronizada con el estado real de los botones en el mapa.

Ahora nuestra lógica está funcionando como se esperaba.
Solo queda un detalle importante: crear un efecto visual para dejar claro al jugador cuándo el botón está activo.
Cada vez que un botón es activado, cambiamos directamente su color usando el Tint, resaltando visualmente su estado.
Antes de establecer Active Button en True, añade una Sequence.
Dado que ya no necesitamos tres flujos, podemos eliminar una de las salidas haciendo clic derecho y seleccionando Remove Last Flow Output, manteniendo solo dos caminos.
Luego, accede al Entity secundario del botón llamado ButtonMesh, accede a su Mesh Component, y ajusta el valor de Tint.
En el eje Y, establece el valor en 25, haciendo que el botón aparezca verde cuando se activa.
Esto le proporciona al jugador una clara retroalimentación visual cada vez que se presiona un botón, mejorando la legibilidad y respuesta de la interacción dentro del juego.

De la misma manera, restauraremos el color original del botón cuando se vuelva inactivo.
Usa la misma lógica, pero en el flujo donde ajustamos Active Button a False.
En ese momento, accede nuevamente al Entity secundario ButtonMesh, obtén su Mesh Component, y ajusta el valor de Tint.
Para volver al color predeterminado, simplemente establece todos los valores de Tint de nuevo en 1, restaurando el estado visual original del botón.
De esta manera, cada vez que el botón se desactiva, también volverá a su apariencia inicial, dejando claro al jugador que puede ser activado nuevamente.

Al seleccionar una instancia de plantilla de botón que añadimos a la escena, podemos acceder a sus propiedades y cambiar el valor de Active Time.
De esta forma, cada botón puede tener una duración de activación diferente y funcionar de forma independiente.
Esto nos da más flexibilidad para crear desafíos variados dentro del nivel, ya que cada botón puede ser configurado de manera individual sin cambiar la lógica principal del sistema.

Con esto, podemos agregar tantos botones como queramos al mapa, cada uno con un tiempo de activación diferente y comportamiento independiente.
La plataforma sigue automáticamente esta configuración sin requerir ajustes manuales, porque el conteo se realiza en tiempo de ejecución.
El sistema también se mantiene sincronizado con el estado real del juego. A medida que los botones se activan y desactivan, el valor global se actualiza, y la plataforma reacciona cuando se cumple la condición, siendo eliminada de la escena en el momento correcto.
Además de la lógica, agregamos una retroalimentación visual importante para el jugador.
Cambiar el color del botón cuando se activa y restaurar su apariencia original cuando se desactiva hace que el sistema sea mucho más claro e intuitivo. El jugador puede entender visualmente qué botones están activos y cuáles aún necesitan atención.
Al final, creamos un sistema modular y escalable que combina la comunicación entre Entidades, control centralizado a través de la Escena, y retroalimentación visual directa en el mundo del juego.
Esta misma estructura puede expandirse fácilmente para puertas, plataformas, ascensores, rompecabezas, trampas, desafíos cronometrados y muchos otros eventos interactivos.
