Nodos y terminología¶
Antes de continuar conviene recalcar que la terminología Nodo hay que usarla con cuidado. Cuando nos referimos a los Nodos de Visual Script (o generalmente Nodos) nos referimos a las pequeñas cajitas que conectas con líneas, y que son parte de un gráfico. Cuando nos referimos a Nodos de escena, esto implica que nos referimos a los elementos que configuran una escena, y que son parte del árbol de dicha escena. El nombre es similar pero su función es diferente. Cuando nos refiramos a Nodo aquí nos estaremos refiriendo a un Nodo de visual script si no se indica lo contrario.
Propiedades de los nodos¶
Como en otras implementaciones se lenguajes visuales de código, cada nodo tiene propiedades editables. En Godot, no obstante, intentamos evitar un excesivo uso de controles editables por el bien de la legibilidad.
Los nodos todavía muestran la información requerida como texto, pero la edición se realiza a través del Inspector. Para editarlos, selecciona cualquier nodo y edita sus propiedades en el Inspector.
Puertos y conexiones¶
La programación en Godot Visual Scripting se realiza a través de Nodos y Conexiones de Puertos dentro de cada función.
Puertos¶
Los nodos en Godot Visual Scripting tienen Puertos. Éstos son los puntos finales que aparecen a la izquierda y derecha de los nodos y que se pueden usar para hacer Conexiones: Hay dos tipos de Puertos: Secuencias y Datos.
Los Puertos de Secuencia (sequence ports) indican el orden en el que se ejecutan las operaciones. Típicamente cuando un Nodo es procesado, irá al siguiente nodo desde uno de los puertos a su derecha. Si no hay nada conectado, la función puede terminar, o se puede intentar otra salida Puerto de secuencia (esto depende del nodo). Gracias a esto, puede seguir el flujo lógico dentro de una función siguiendo las líneas blancas. No todos los Nodos tienen Puertos de Secuencia. De hecho, la mayoría no los posee.
Los Puertos de Datos contienen valores tipados. Los tipos pueden ser cualquier tipo regular de Godot, como un booleano, un entero, una cadena de texto, un Vector3, un array y cualquier Objeto o Escena, etc. Un Puerto de Datos en la parte derecha de un nodo se considera una salida, mientras que un puerto a la izquierda es una entrada. Conectando estos permitimos que la información fluya hacia el siguiente nodo.
No todos los tipos de Puertos de Datos son compatibles y permiten la interconexión. Presta especial atención a los colores y los iconos, cada tipo tiene una representación diferente:
Conexiones¶
La conexión es un proceso relativamente sencillo. Arrastra un Puerto de salida hacia un Puerto de entrada.
Desconectar necesita un poco más de práctica. La desconexión de los Puertos de Datos se consigue arrastrando la Entrada hacia afuera, mientras que para los Puertos de Secuencia, esto se consigue arrastrando hacia fuera la Salida.
Esto puede parecer extraño al principio, pero es así porque los Puertos de Datos son 1:N (una salida única puede conectarse a muchas entradas), mientras que los Puertos de Secuencia son N:1 (Muchas salidas pueden conectarse a una única entrada).
Conectando a un espacio vacío (arrastrar para conectar pero soltar en un espacio vacío) es sensible al contexto, mostrará una lista de operaciones comunes. Para secuencias, serán nodos condicionales:
Mientras que, para datos, se abrirá el menú contextual set/get/call:
Agregando nodos¶
Finalmente llegamos a la parte divertida! Pero, antes de explicar en detalle lo que hace cada tipo de nodo, echemos un vistazo a cómo son agregados y tratados los nodos más comunes.
Accediendo a nodos de la escena¶
Una de las tareas más comunes es acceder a Nodos del árbol de escena (de nuevo, no confundir con Nodos de Visual Script). Arrastrando del árbol de escena y soltando en el área de trabajo, pedirá seleccionar un método (a veces referido como función miembro) de este nodo.
Mientras que acceder a propiedades es deseable en la mayoría de los casos (más sobre esto a continuación), a veces llamar métodos puede ser útil también. Los métodos ejecutan acciones en objetos. En el caso anterior, el puntero del ratón puede ser transportado a una posición en coordenadas locales del control. Otro caso de uso común poner en cola un nodo para borrarlo, lo que se hace con el método queue_free.
Se debe tener en cuenta que esto sólo funciona si la escena siendo editada contiene el Visual Script en uno de los nodos! De otro modo, se mostrará una advertencia.
Accediendo a propiedades de nodos de la escena¶
Este es el modo más común de editar Nodos de la escena en Visual Scripting. Seleccione un Nodo de la escena del Árbol de escena, vaya al Inspector, encuentre el Nombre de la propiedad que quiere editar (el nombre, no el valor!) y arrástrelo al área de trabajo:
El resultado será que este valor podrá ser cambiado desde el script escribiendo a un Puerto de Datos (Data Port).
Si en cambio deseas leer este valor, arrastra el nodo de nuevo pero mantén presionada la tecla Ctrl (o Cmd en macOS). Esto creará un getter:
En este caso, el valor podrá ser leído desde un Puerto de datos.
Variables¶
Las variables son contenedores de memoria locales al script que pueden contener un valor. Este valor se puede leer desde cualquiera de las funciones del script o desde otros scripts mediante el método descrito en el paso anterior.
Para agregar una variable, presione el botón "+" en la sección Variables del panel Miembros. Doble clic en la nueva variable para renombrarla:
Clic derecho en la variable permite configurar sus propiedades:
Como puede verse, el tipo y valor iniciales de la variable pueden ser cambiados, así como algunos hints (tipos) de propiedades. Seleccionando la opción "Export" se hace que la variable sea visible en el Inspector cuando se selecciona el nodo. Esto también la hace disponible a otros scripts mediante el método descrito en el paso anterior.
Para utilizar una variable en el script, simplemente arrástrela al área de trabajo para crear un getter:
Del mismo modo, manteniendo presionado Ctrl (o Cmd en macOS) para crear un setter:
Señales¶
También es posible crear tus propias señales en un script y usarlas. Para esto, realiza los mismos pasos utilizados para variables en el paso anterior, pero para la sección Señales:
Una señal también puede ser editada con el menú de clic derecho para personalizar sus argumentos:
La señal que has creado aparecerá en el Inspector junto con las señales de nodo incorporadas. Esto permite conectarlo desde otro script procedente de otro Nodo de la Escena:
Finalmente, para emitir la señal, simplemente arrástrela al área de trabajo:
Recuerda que la emisión de una señal es una operación secuenciada, por lo que debe venir de un puerto Sequence.
Agregando más nodos¶
Ahora que lo básico está cubierto, hablemos de la gran la gran cantidad de nodos de utilidad (utility nodes) disponibles para tu área de trabajo! En el panel de miembros de abajo, existe la lista de todos los tipos de nodos disponibles:
Presionar Ctrl + F (o Cmd + F en macOS) le permite buscar en la lista.
Cualquiera de ellos peude ser arrastrado a la escena. A diferencia de los nodos(ejemplo, arrastrar una propiedad del inspector establece que el contexto del nodo se edita automáticamente), éstos se añaden sin ninguna información "contextual", por eso se tiene que hacer manualmente.
Recuerda que puedes verificar la clase de referencia a cada nodo que se realiza, ya que estan documentados, que se mencionan, en un breve resumen de los siguientes tipos de nodos:
Constantes¶
Nodos constantes pueden proveer valores que, aunque no cambian con el tiempo, pueden ser útiles como valores de referencia. En la mayor parte del tiempo son enteros o flotantes.
La primera es "Constant" que permite seleccionar cualquier valor de cualquier tipo como constante, desde un entero (42) hasta una cadena ("Hello!"). En general, este nodo no se utiliza tan a menudo debido a los valores de entrada por defecto en Data Ports, pero es bueno saber que existe.
El segundo es el nodo GlobalConstant, que contiene una larga lista de constantes para tipos globales en Godot. Allí encontrarás constantes útiles para referirse a nombres clave, botones de joystick o ratón, etc.
El tercero es MathConstant, el cual provee constantes típicas en matemáticas como PI, e, etc.
Datos¶
Los nodos Data tratan todo tipo de acceso a información. Cualquier información en Godot es accedida mediante esos nodos, esos son los más importantes para usar y también muy diversos.
Hay muchos tipos de nodo de interés aquí, a continuación hay una breve descripción de ellos:
Acción¶
Los nodos Action son vitales cuando se trata la entrada desde un dispositivo. En el siguiente ejemplo, el control es trasladado hacia la derecha cuando la acción "move_right" es presionada.
Singleton de Motor¶
Los Engine Singletons son interfaces globales (pueden ser accedidas sin una referencia, y están siempre disponibles a diferencia de Nodos de la Escena). Tienen muchos propósitos pero, en general, son útiles para acceso a funciones de bajo nivel del SO.
Recuerda que arrastrando una conexión a un espacio vacío ayudará a llamar funciones o asignar/obtener (set/get) propiedades en los siguientes:
Variables locales¶
Estos son nodos que puedes usar como almacenamiento temporal para tus gráficos. Asegúrate que todos tienen el mismo nombre y tipo al usarlos y que hacen referencia a la misma parte de memoria.
Como se puede ver arriba, hay dos nodos disponibles: un getter simple y un setter secuenciado (la configuración requiere un puerto de secuencia).
Nodo Scene¶
Esto es sólo una referencia a un nodo en el árbol, pero es más fácil usar este nodo arrastrando el nodo actual desde el árbol de escena hasta el área de trabajo (esto lo creará y configurará).
Propio¶
En raras ocasiones, se puede desear pasar este Nodo de Escena como argumento. Se puede usar para llamar funciones y establecer/obtener propiedades, o arrastrar nodos (o eventos del mismo nodo que tenga el script) desde el Árbol de Escenas hasta el área de trabajo para esto.
Árbol de Escenas¶
Este nodo es similar al nodo Singleton porque hace referencia al SceneTree, que contiene la escena activa. El SceneTree, sin embargo, sólo funciona cuando el nodo se encuentra activo en la escena, de lo contrario, el acceso a él devolverá un error.
SceneTree permite hacer muchas cosas de bajo nivel, como cambiar las opciones de ajuste de pantalla, llamar grupos, crear temporizadores o cargar otra escena principal. Es una clase con la que hay que estar familiarizado.
Precargar¶
Esto hace la misma función que preload() en GDScript. Mantiene este recurso cargado y listo para usar. En lugar de instanciar el nodo, es más sencillo arrastrar el recurso deseado desde el panel de Sistema de Archivos hasta el área de trabajo.
Ruta de Recursos¶
Este nodo es un simple helper para obtener una cadena con una ruta a un recurso que puedes elegir. Es útil en funciones que cargan cosas desde el disco.
Comentario¶
Un nodo Comentario funciona como un nodo que puede ser redimensionado para colocarlo alrededor de otros nodos. No tratará de obtener el foco o ser puesto al frente al seleccionarlo. También se puede utilizar para escribir texto en él.
Control de Flujo¶
Los nodos de control de flujo permiten que la ejecución tome diferentes caminos, normalmente dependiendo de una condición determinada.
Condición¶
Este es un nodo simple que compara un puerto booleano. Si es true
, continuará por el puerto secuencia "true". Si es false
, irá por el segundo. Después de ir por cualquiera de ellos, sigue por el puerto "done". Dejar los puertos de secuencia desconectados está bien si alguno de ellos no es usado.
Iterador¶
Algunos tipos de dato en Godot (por ejemplo array y diccionarios) son iterables. Esto significa que una porción de código puede ser ejecutada por cada elemento que tiene.
El nodo Iterator va a través de todos los elementos y, por cada uno, pasa por el puerto secuencia "each", haciendo que el elemento esté disponible en el puerto de datos "elem".
Cuando está listo, va por el puerto secuencia "exit".
Return¶
Algunas funciones pueden retornar valores. En general, para las funciones virtuales, Godot agregará el nodo Return. Un nodo return fuerza a la función a terminar.
Secuencia¶
Este nodo es útil principalmente para organizar el grafo. Llama a sus puertos secuencia en orden.
TypeCast¶
Este es un nodo útil y de uso común. Puedes usarlo para asignar argumentos u otros objetos al tipo deseado. Después, puedes arrastrar el objeto de salida para obtener su completa finalización.
También es posible convertir a un script, lo que permite obtener propiedades y funciones del script:
Switch¶
El nodo Switch es similar al nodo Condition, pero iguala muchos valores al mismo tiempo.
While¶
Esta es una forma primitiva de iteración. La salida de secuencia "repeat" será llamada tantas veces como la condición en el puerto de datos "cond" se cumpla.
Funciones¶
Los Function son ayudantes, la mayoría del tiempo deterministas. Toman algunos argumentos de entrada y devuelven una salida. En general no son secuenciados.
Integrado¶
Hay una lista de utilidades integradas. La lista es casi idéntica a la de GDScript. La mayoría de ellos son funciones matemáticas, pero otras pueden ser útiles para facilitar operaciones comunes. Asegúrate de echar un vistazo a la lista en algún momento.
By Type¶
Estos son los métodos disponibles para los tipos básicos. Por ejemplo, si quieres un producto punto, puedes buscar "punto" en lugar de la categoría Vector3. En la mayoría de los casos sólo hay que buscar en la lista de nodos, debería ser más rápido.
Call¶
Esta es la llamada a nodo genérica. Es raramente utilizada directamente, se utiliza arrastrando desde un nodo ya configurado.
Constructores¶
Esas son todas las funciones necesarias para crear tipos de datos básicos de Godot. Por ejemplo, si necesitas crear un Vector3 desde 3 floats, se debe utilizar un constructor.
Destructor¶
Es lo contrario al Constructor, permite separar tipos básicos en sus sub-elementos.
Emitir Señal¶
Emite señales desde cualquier objeto. En general no es tan útil, ya que arrastrar una señal al área de trabajo es lo más eficaz.
Get/Set¶
Nodo Setter/Getter genérico. Arrastrando propiedades desde el Inspector suele ser mejor, ya que aparecen configuradas al soltar.
Wait¶
El nodo Wait suspende la ejecución de la función hasta que suceda algo (de hecho, pueden pasar muchos frames hasta llegar resumirla). Por defecto los nodos permiten esperar un frame, un fixed frame o una cantidad de tiempo dada antes de resumir la ejecución.
Yield¶
Este nodo suspende completamente la ejecución del script y hará que la función retorne un valor que puede ser utilizado para continuar la ejecución.
Señal Yield¶
Lo mismo que Yield, pero espera a que determinada señal sea emitida.
Index¶
Operador de indexación genérico, no muy usado pero es bueno que esté por si acaso.
Operadores¶
Se trata en su mayoría de operadores genéricos como sumas, multiplicaciones, comparaciones, etc. De forma predeterminada, aceptan cualquier tipo de datos (y se producirá un error en tiempo de ejecución si los tipos introducidos no coinciden con los del operador). Siempre se recomienda configurar el tipo correcto para que los operadores detecten los errores rápidamente y faciliten la lectura del grafo.
Expression Node¶
Entre los operadores, el nodo Expression es el más potente. Si se usa bien, permite simplificar enormemente los visual scripts complejos desde el punto de vista matemático o lógico. Escribe cualquier expresión en él y se ejecutará en tiempo real.
Los nodos Expression pueden:
Ejecutar expresiones lógicas y matemáticas basadas en entradas personalizadas (ej. "a*5+b", donde a y b son tipos de entrada personalizados):
Acceder a variables locales o propiedades:
Utiliza la mayoría de las funciones built-in disponibles en GDScript, como
sin()
,cos()
oprint()
, así como constructores comoVector3(x, y, z)
,Rect2(...)
, etc.:
Funciones API Call:
Usar modo secuenciado, lo que tiene más sentido en caso de respetar el orden de procesamiento: