¿Por qué son útiles los Blueprints Interface para hacer botones?

Para hacer botones, he hecho algunos Blueprints complejos con mucha lógica para lograr buenos efectos y jugabilidad. En este vídeo de Youtube puedes ver el resultado:

Botones - Vista previa de funciones

Para hacerlos hice una estructura de herencia similar a la que he hecho con las lámparas, así tengo las mismas características de lámpara en mis botones: ruido, chispas, luz, etc. No iré paso a paso porque mis Blueprints de los botones son muy complejos, pero explicaré las ideas generales sobre las "interfaces de Blueprints" que me permiten hacer la interacción de los botones.

¿POR QUÉ NECESITO INTERFACES BLUEPRINT?

Ahora tengo un nuevo problema: cualquier botón de mi juego puede interactuar con cualquier otro objeto u objetos. Por ejemplo: un botón puede encender o apagar un grupo de luces en una habitación, activar un evento como girar una vez una puerta giratoria, etc.

Las puertas y las luces son objetos muy diferentes, y dentro de ambos pueden existir muchos subtipos de puertas y luces. Entonces necesito algún tipo de mecanismo para permitir que un botón reconozca cualquier objeto en el juego y ejecute su lógica.

En el otro lado tendremos un botón que el jugador puede presionar con el personaje del juego. Un botón puede ser un objeto que puede variar desde un simple botón hasta un interruptor con diferentes mallas, efectos, luces, etc. Por lo tanto, también necesitamos un mecanismo para que el juego reconozca un botón y haga que el personaje del jugador lo presione cuando presionamos el botón de acción en nuestro teclado, controlador, etc.

Aquí es donde una "Interfaz Blueprint" puede ayudarnos.

Una "Interfaz Blueprint" es un tipo especial de Blueprint que no se puede instanciar y no puede tener ninguna lógica interna, pero debe tener al menos una declaración de función. Podemos definir cualquier función que necesitemos con sus entradas y salidas de datos.

Entonces podemos aplicar esta "Interfaz Blueprint" en cualquier otro "Blueprint" y este tendrá los métodos de su interfaz, luego tenemos que especificar la lógica a aplicar para cada función de interfaz en este "Blueprint". Esto nos permite hacer un comportamiento diferente en cada "Blueprint" para la misma función.

Por ejemplo: haré una interfaz de interruptor que me permita ejecutar una función en un objeto de juego llamado "BPI_BooleanSwitchable" para encender o apagar una luz, una máquina, un motor, etc. Dentro de esta interfaz tenemos una función llamada "Switch".

ejemplo de interfaz de botones de blueprint

Puedo usar esta interfaz en puertas y luces y luego un botón puede convertir cualquiera de estos objetos en "BPI_BooleanSwitchable" e iniciar su función "Switch" cuando el jugador presiona el botón.

¿CÓMO ACTIVO UN BOTÓN (o algo) EN EL JUEGO?

En primer lugar, agregué un nuevo colisionador a mi personaje para detectar objetos interactivos llamado "InteractableCollider":

caracteres de botones blueprint

Cuando un objeto que tiene la interfaz BPI_Interactable está dentro del colisionador, entonces se puede activar. Entonces, cuando el jugador presiona el botón de acción en su controlador y si hay un objeto dentro del colisionador interactivo, intenta convertirlo en un objeto BPI_Interactable y lanzar su lógica.

Este es el detalle de la lógica del objeto de mi personaje Blueprint:

botones blueprint carácter 2

El BPI_Interactable es una interfaz de Blueprint que tiene el método "Interactuate" para activar un botón, tomar un objeto o lo que necesite hacer. Si es un botón, activará la lógica de otros objetos asociados al botón. Luego uso la interfaz BPI_Interactable para crear botones como mi BP_Base_Button.

DESDE UN BOTÓN ¿CÓMO ACTIVO OTRAS LÓGICAS DE OBJETOS?

Entonces necesito objetos que respondan al botón pero no al jugador cómo, por ejemplo, una máquina que empieza a funcionar cuando la activamos. Cada botón tiene una serie de objetos que se pueden activar, para reconocerlos, cada objeto tendrá una interfaz BPI_Triggerable.

Esta interfaz tiene un método que es útil para activar sus objetos: el método Launch. Cuando el jugador presiona el botón, el botón proyecta sus objetos activables en BPI_Triggerable y luego cada objeto ejecuta su propia lógica.

Aquí muestro la lógica del botón BP_Base_Button. Para que sea fácil de entender, oculto toda la lógica sobre hacer sonidos, luces, etc. y solo muestro la parte importante de la lógica del botón:

disparador de botones blueprint

Como puede ver al final, ejecuto una función de "Launch" dentro del objeto BPI_Triggerable.

Este es un buen punto de partida para hacer botones más complejos.

¿QUÉ PASA CON EL BOTÓN DE TIPO INTERRUPTOR?

El botón interruptor es útil para cosas que pueden tener dos estados, por ejemplo serán cosas como lámparas u otros botones que pueden estar activos o no, puertas que pueden estar abiertas o cerradas, etc. Para lograrlo hice una interfaz BPI_BolleanSwitchable que tiene la función "Switch".

Mi interruptor es una evolución de mi botón base BP_Base_Button llamado BP_Base_Switch. Anulará (override) la función LaunchObjectLogic gracias a la herencia y, en lugar de objetos BPI_Triggerable, lanzará objetos BPI_BooleanSwitchable. Pero este es un botón especial que albergará el estado de las cosas que estarán activas o no, por lo que primero debemos modificar nuestro BP_Base_Button nuevamente.

Agregué una función de "Update" que será útil para hacer modificaciones cuando se presione el botón. En el BP_Base_Button, esta función permanecerá inválida porque no necesito hacer nada en este punto y será útil solo para ser anulada (override) por Blueprints hijos.

Esta imagen muestra las partes importantes de la lógica del botón:

botones blueprint activan 2

Como se puede ver, entre el inicio y el final de este proceso llamo a la función "Update" porque si quiero hacer modificaciones en los datos del botón, es obligatorio hacerlo antes de que intentemos lanzar las lógicas de los objetos.

Ahora hice el BP_Base_Switch y en este Blueprint configuré la herencia para tener el BP_Base_Button como Blueprint padre y esto quiere decir que ya tengo toda la lógica que vimos antes y la interfaz BPI_Interactable aplicada.

Entonces anulé las funciones (override) Update y LaunchObjectLogic:

interruptor de botones blueprint

Lo importante en el método Update es que cambia el estado booleano del interruptor y en el LaunchObjectLogic en lugar del BPI_Triggerable están proyectando a BPI_BooleanSwitchable. También envia el estado del interruptor al objeto a través de la función Switch.

ESQUEMA

Para tratar de ver todo esto un poco más claro echa un vistazo a este esquema. Es una representación de este mecanismo de interacción y botones:

botones blueprint final