Documentación técnica de Visual
Scripting en Unity 2D (Unity 2022.3.5f)
¿Qué es el Visual Scripting de Unity?
El Visual Scripting de Unity es un sistema que permite implementar la lógica de un juego
mediante diagramas de nodos visuales, en lugar de escribir código en C#. En vez del
código tradicional, se utilizan gráficos de nodos que representan elementos de
programación (variables, operadores, métodos, etc.), conectados por transiciones que
indican el orden de ejecució[Link]. Esto lo hace accesible tanto para programadores
como para personas sin experiencia en código. Unity Visual Scripting soporta arrastrar y
soltar nodos en un lienzo para crear la lógica, facilitando la colaboración rápida entre
programadores, artistas y diseñadores, lo que acelera el prototipado e iteración en los
[Link]. En versiones recientes del editor (Unity 2021 en adelante), Visual Scripting
ya viene integrado de forma nativa, sin necesidad de instalar paquetes
[Link] (anteriormente se conocía como Bolt en Unity 2018–2020).
Unity ofrece dos tipos principales de gráficos (diagrams) para Visual Scripting: grafo de
flujo (Script Graph) y grafo de estado (State Graph). El grafo de flujo es el más común y
define secuencias lógicas o comportamientos (por ejemplo, mover un personaje
continuamente o reaccionar a un evento) mediante nodos conectados en orden de
ejecució[Link]. El grafo de estado, por su parte, permite crear máquinas de estado
(State Machines) para lógica de alto nivel, donde se definen estados y transiciones entre
ellos (útil para IA, cambios de nivel, etc.)[Link]. En esta documentación nos enfocaremos
en los grafos de flujo (Script Graphs), que son los utilizados típicamente para
comportamientos de objetos en juegos 2D.
Para usar Visual Scripting en Unity 2D, se crea un Script Graph ([Link]., desde Assets →
Create → Visual Scripting → Script Graph) y se asigna a un objeto de juego mediante un
Script Machine (componente que ejecuta el gráfico en ese GameObject). Al abrir el gráfico,
se muestra el Graph Editor, un lienzo donde podemos colocar y conectar nodos para
construir la lógica. En este editor se utiliza un buscador contextual (denominado Fuzzy
Finder) para añadir nodos: haciendo clic derecho se abre un menú donde se pueden buscar
nodos por nombre o navegar por categorí[Link].
Nodos y conexiones: Cada nodo en el gráfico tiene puertos de entrada (a la izquierda) y/o
salida (a la derecha). Los puertos de flujo de control aparecen como flechas (triángulos) y
determinan el orden de ejecución; los puertos de datos suelen mostrarse como círculos o
cuadrados de colores e indican valores que se pasan entre nodos. Para conectar nodos, se
arrastra desde un puerto de salida hacia un puerto de entrada compatible. Las conexiones
de flujo se representan con líneas blancas, mientras que las conexiones de datos se
muestran con líneas de colores según el tipo de dato (por ejemplo, float, booleano, Vector2,
etc.)[Link]. Un puerto de flujo de salida de un nodo debe conectarse a un puerto
de flujo de entrada de otro nodo para establecer la secuencia de ejecución. Asimismo, los
puertos de datos de salida (por ejemplo, un número) se pueden conectar a puertos de
entrada de datos de otro nodo que espere ese tipo de valor.
Nodos clave organizados por categoría
A continuación se describen los nodos principales de Visual Scripting organizados en
categorías, junto con sus funciones y conexiones más importantes. Esta lista sirve como
referencia rápida para comprender los componentes básicos de lógica, eventos,
movimiento, colisiones y UI en Unity 2D.
Nodos de Lógica
Los nodos de lógica controlan el flujo del programa (condicionales, bucles, etc.) y
operaciones fundamentales. Algunos nodos lógicos clave son:
● If (Branch): evalúa una condición booleana y desvía el flujo según el resultado. Este
nodo corresponde a un “si… entonces / si no” clásico: si la condición es true
ejecuta la rama True, de lo contrario ejecuta la rama [Link]. Tiene
un puerto de entrada de flujo, un puerto de salida True y otro False, y un puerto de
entrada de dato para la condición (booleano). Se usa para ejecutar diferentes
conjuntos de nodos según una condición.
● Switch: permite ramificar el flujo en múltiples caminos según el valor de una variable
(por ejemplo, un enum, entero o string). Tiene un puerto de entrada de flujo y varios
puertos de salida, uno por cada caso o valor coincidente, más un puerto Default
para valores no [Link]. Es útil para manejar
varias posibilidades sin anidar muchos If.
● While Loop: implementa un bucle while. Repite la ejecución de una serie de nodos
mientras la condición sea verdadera, evaluándola antes de cada
iteració[Link]. Posee un puerto de flujo de entrada, uno de salida para
el cuerpo (lo que se repite) y otro de salida Exit que se activa al terminar el bucle.
Nota: Se debe tener cuidado de no crear bucles infinitos (condición siempre
verdadera), ya que bloquearían el [Link].
● For Loop: bucle for tradicional con índice numérico. Requiere valores inicial, final y
el incremento. Ejecuta el cuerpo del bucle aumentando el índice en cada iteración
hasta alcanzar el valor final, y expone el índice actual como salida de datos en cada
iteració[Link]. Tiene puertos de entrada similares al While (entrada,
cuerpo, salida exit) y puertos de datos para el índice y límites.
● For Each Loop: itera sobre cada elemento de una colección (lista, array, etc.). En
cada iteración provee como salidas el elemento actual y su índice (y opcionalmente
clave/valor en un diccionario)[Link]. Útil para recorrer listas de objetos o
valores. También tiene puertos de flujo para cuerpo y salida final.
● Break Loop: permite salir anticipadamente de un bucle. Cuando este nodo se activa
dentro del cuerpo de un loop, provoca que se salte inmediatamente al puerto de
salida Exit del bucle, terminando la iteración aunque la condición no haya fallado
aú[Link]. Sirve para cortar bucles en base a alguna condición interna.
● Operadores lógicos y aritméticos: Además de los nodos de flujo, en Visual
Scripting encontramos nodos para operaciones lógicas (AND, OR, comparaciones
igual, mayor que, etc.) y aritméticas (suma, resta, multiplicación, división). Por
ejemplo, el nodo Comparison (==, !=, <, >, etc.) devuelve un booleano al comparar
dos valores; los nodos Add, Multiply, etc., realizan operaciones matemáticas. Estos
nodos tienen puertos de datos de entrada (operandos) y puertos de datos de salida
(resultado). Se usan junto con nodos como If o Set Variable para implementar
cálculos y condiciones.
● Variables: El manejo de variables en Visual Scripting se realiza con nodos
especiales de Get y Set. Por ejemplo, Get Variable obtiene el valor de una variable
dada (identificada por su nombre)[Link], y Set Variable asigna un nuevo
valor a una variable (también identificada por nombre)[Link]. Unity Visual
Scripting soporta distintos alcances de variables: por grafo (Graph variables), por
objeto (Object variables ligadas a un GameObject), por escena (Scene variables),
globales de juego (Application) e incluso persistentes entre sesiones (Saved
variables)[Link]. Al usar Get/Set Object Variable, por ejemplo, se puede
especificar el GameObject objetivo (por defecto usa Self, el mismo
objeto)[Link]. Las variables son tipadas dinámicamente (pueden cambiar
de tipo según el valor asignado). Un nodo Is Defined permite chequear si una
variable con cierto nombre [Link]. En un grafo, las variables
definidas aparecen en la pestaña Blackboard y pueden ser arrastradas al lienzo para
crear nodos Get/Set rá[Link].
Nodos de Eventos
Los nodos de eventos representan sucesos o condiciones que inician la ejecución del
grafo. Son puntos de entrada al flujo del script: se activan automáticamente cuando ocurre
el evento correspondiente en Unity. Los nodos de evento se distinguen por su color verde y
porque solo tienen puerto de salida de flujo (no reciben una entrada de otro
nodo)[Link]. Cuando se activan, disparan el flujo de ejecución conectado a su salida.
Algunos eventos esenciales son:
Imagen: Nodo de evento On Keyboard Input, con puertos para tecla (Key) y acción (Action),
y un puerto de salida de flujo (flecha).
● Start: evento que se llama una vez cuando el Script Graph se habilita por primera
vez en un objeto (equivalente a Start() en un script C#). Se activa al inicio de la
escena o cuando el objeto entra en juego. Normalmente se usa para inicialización de
variables, estados iniciales, etc. Unity por defecto crea un nodo Start en los nuevos
grá[Link].
● Update: evento que se ejecuta en cada frame (equivalente a Update() en C#).
Mientras el objeto y el gráfico estén activos, Update se disparará constantemente
una vez por fotograma, enviando flujo de ejecución continua. Se utiliza para lógica
dependiente del tiempo transcurrido, como movimiento frame a frame, chequeo
continuo de condiciones, etc. (Típicamente se combinará con cálculos con
DeltaTime o nodos de tiempo para movimiento suave). Los nuevos gráficos suelen
incluir un nodo Update por defecto junto al [Link].
● On Keyboard Input: evento específico para entradas de teclado. Se activa cuando
el usuario presiona una tecla definida. Este nodo tiene puertos de datos Key (tecla a
detectar) y Action (tipo de acción)[Link]. La propiedad Action puede ser:
○ Down: el evento dispara una única vez en el momento exacto en que la tecla
es [Link].
○ Up: dispara una vez cuando la tecla es soltada.
○ Hold: permanece disparando continuamente mientras la tecla esté mantenida
pulsada (se activa cada frame durante la pulsación)[Link].
● El nodo On Keyboard Input es muy útil para control de personajes. Por ejemplo, se
pueden usar cuatro nodos On Keyboard Input (uno para cada flecha de cursor)
configurados con Action = Hold para mover un personaje mientras se mantienen
pulsadas las [Link]. Cada uno de estos nodos de evento se conectará a la
lógica de movimiento correspondiente (ver ejemplos prácticos más adelante). Al
igual que Start/Update, este evento solo tiene salida de [Link], que se activa
cuando ocurre la acción de la tecla especificada.
● On Mouse Input / On Mouse Down: de forma análoga al teclado, existen eventos
para el mouse. Por ejemplo, On Mouse Down se activa al hacer clic con el botón del
ratón sobre un objeto Collider, y On Mouse Up al soltarlo. También hay eventos
como On Mouse Enter/Exit al pasar el cursor sobre un objeto. Estos eventos son
útiles para interacciones con objetos 2D si utilizan colliders (por ejemplo, clicks sobre
sprites).
● On Collision/Trigger events: (detallados en la sección de Colisiones más abajo)
Unity Visual Scripting provee eventos físicos como On Collision Enter 2D o On
Trigger Enter 2D que se disparan cuando ocurren colisiones o interacciones de
trigger entre objetos con colliders. Son fundamentales para la detección de
colisiones en juegos 2D (p. ej., cuando el personaje toca un enemigo o recoge un
ítem). Cada uno de estos nodos es un evento verde con un puerto de salida de flujo,
y suele incluir puertos de datos con información de la colisión (el otro objeto
involucrado, detalles del impacto, etc.).
● On Button Click: evento de la categoría UI (GUI) que se activa al hacer clic en un
botón de la interfaz de usuario (UI Button). Este nodo facilita vincular la pulsación de
un botón UI con la lógica de Visual Scripting, en lugar de usar los scripts C#
tradicionales de UI. Se puede encontrar en Events > GUI > On Button Click en el
buscador de [Link]. Solo tiene salida de flujo y se dispara cada vez
que el usuario hace click en el botón asignado. (Ver más en sección Nodos de UI).
● Custom Event: Unity permite definir eventos personalizados enviados desde un
lugar del juego y capturados en un grafo. Un Custom Event es un nodo de evento
donde uno elige un nombre (por ej. "OnDamage") y un número de parámetros; este
evento se puede Trigger (disparar) desde otro lugar usando el nodo Trigger
Custom Event o incluso desde código C#[Link]. Los
eventos personalizados son avanzados pero muy poderosos para comunicación
entre diferentes gráficos u objetos (por ejemplo, un objeto enemigo puede disparar
un evento "OnDamage" para que el jugador reduzca su salud). Si no hay ningún
receptor del evento, no ocurre nada (no produce error)[Link]. (Nota: Para
principiantes, los Custom Events pueden reservarse para más adelante, pero vale
saber que existen.)
● Unity Event: este nodo permite responder a UnityEvents expuestos en
componentes a través del inspector (por ejemplo, el evento OnClick de un UI Button,
o eventos personalizados en scripts). Para usarlo, se configura el componente en el
Inspector para que en su UnityEvent llame a la función TriggerUnityEvent del
Script Machine, pasando un nombre de evento. En el gráfico, se añade un nodo
Unity Event con ese nombre para [Link]. Esta es otra forma
de conectar eventos de UI o de otros sistemas con Visual Scripting, aunque suele
requerir más configuración manual. En la práctica, para botones UI es más sencillo
usar directamente el evento On Button Click mencionado antes.
En resumen, los nodos de eventos son el punto de inicio de cualquier comportamiento en
Visual Scripting: al ocurrir algo (inicio del juego, frame nuevo, pulsación de tecla, colisión,
clic de botón, etc.), el nodo de evento correspondiente dispara y activa la cadena de nodos
conectados a su salida, ejecutando la lógica diseñada.
Nodos de Movimiento
En juegos 2D, el movimiento de objetos puede lograrse tanto mediante la manipulación
directa de su Transform (posición, rotación) como mediante la aplicación de física 2D
(fuerzas, velocidades). Unity Visual Scripting proporciona nodos para ambas formas:
Imagen: Nodo de acción [Link], con puertos de entrada de flujo (triángulo
izquierdo), salida de flujo (triángulo derecho) y puertos de datos X, Y, Z para la distancia a
mover en cada eje.
● [Link]: mueve (traslada) un objeto una distancia específica en los
ejes X, Y, Z. Este nodo aplica un desplazamiento relativo a la posición actual del
objeto. Tiene puertos de datos para las cantidades a mover en X, Y y Z,
generalmente en coordenadas locales del [Link]. Por ejemplo,
Translate(0.1, 0, 0) moverá el objeto 0.1 unidades a la derecha (eje X
positivo) en su espacio local. Si se usa en un objeto 2D que solo se mueve en plano,
normalmente Z=0. Un valor positivo en X mueve a la derecha y negativo a la
izquierda; en Y, positivo hacia arriba y negativo hacia [Link]. Este nodo
también tiene un puerto de entrada de flujo (para ejecutar la acción) y un puerto de
salida de flujo (para continuar la secuencia). Es útil para controles simples: por
ejemplo, mover un personaje pixel a pixel en cada frame según la entrada del
jugador.
● [Link] / SetRotation: Alternativamente a Translate (que es
relativo), existen nodos para establecer directamente la posición o rotación de un
objeto. Por ejemplo, [Link] toma un Vector3 de posición absoluta y
mueve el objeto a esas coordenadas en la escena. Estos nodos reemplazan la
posición/rotación actual en lugar de sumar a la existente. Se usan para
teletransportar objetos, reiniciar posiciones, etc. Al usarlos se debe tener en cuenta
el sistema de coordenadas (global o local); algunos nodos permiten elegir si la
posición es global o local.
● [Link]: gira un objeto en torno a uno de sus ejes. En 2D, típicamente la
rotación relevante es en Z (rotación en plano). Un nodo [Link](Vector3
EulerAngles) rotará el objeto los grados indicados en X, Y, Z (euler angles) respecto
a su transformación actual. También hay variantes para rotar hacia una dirección
gradualmente. Para juegos 2D simples, la rotación suele usarse para voltear sprites
o para efectos ([Link]., hacer girar un objeto continuamente usando Update).
● [Link]: si se está usando física 2D (componentes Rigidbody2D
en los objetos), esta es la forma de impulsar un objeto. El nodo Rigidbody Add
Force aplica una fuerza vectorial al Rigidbody ([Link]., para saltar, empujar al
personaje, etc.). Tiene puertos de datos para la fuerza (Vector2 o Vector3) y para el
modo (impulso instantáneo, fuerza continua, etc.). Cuando se usa AddForce, Unity
calculará el movimiento resultante según la masa del objeto, gravedad, arrastre, etc.,
en lugar de moverlo directamente como Translate. Es adecuado para movimientos
influenciados por físicas (por ejemplo, un proyectil, o un personaje con gravedad).
También existen nodos como [Link] (para establecer
directamente la velocidad) o [Link] (mover un Rigidbody a
una posición, respetando colisiones).
● Per Second: este nodo de la categoría Time/Math es muy útil al mover objetos en
cada frame. Convierte una cantidad dada (por ejemplo una velocidad por segundo)
en la fracción correspondiente por frame, tomando en cuenta el delta time. En
esencia, divide un valor por la cantidad de frames por segundo, para que el
movimiento sea independiente de la tasa de [Link]. Por ejemplo, si
queremos mover 5 unidades por segundo, Per Second(5) devolverá ~0.083 por
frame (asumiendo 60 FPS). Podemos multiplicar este resultado por algún valor de
velocidad variable. Unity Visual Scripting también provee directamente el nodo
[Link] (tiempo en segundos desde el último frame) y
[Link], que se pueden usar en cálculos manuales. Sin embargo, Per
Second simplifica este ajuste. En la práctica, al usar Update para movimiento
continuo, es recomendable multiplicar las distancias por DeltaTime para que la
velocidad no dependa del rendimiento; este nodo lo facilita.
● Otros nodos de movimiento:
○ Translate Towards / Move Towards: permiten mover linealmente un objeto
desde su posición actual hacia un destino a una velocidad fija.
○ Lerp: interpola linealmente entre dos posiciones o valores según un factor (0
a 1), útil para movimientos suaves o transiciones.
○ Look At: rota un objeto para mirar hacia un punto objetivo (3D
principalmente, aunque en 2D se puede usar para orientar hacia algo en
plano).
● Estos nodos son más avanzados pero vale mencionarlos. Para un principiante,
Translate y AddForce serán los más comunes para mover sprites u objetos en 2D.
Además de mover objetos, a veces queremos detener o eliminar objetos:
● [Link] / WakeUp: para pausar o reactivar la simulación física de un
objeto.
● [Link]: habilita o deshabilita un objeto completo en la escena
(apagándolo o prendiéndolo).
● Destroy: permite destruir (eliminar) un objeto de la escena. Visual Scripting tiene el
nodo [Link](GameObject) que toma una referencia a un objeto y lo
remueve de la escena al ejecutarse (por ejemplo, para eliminar un proyectil al
impactar, o un enemigo al morir). También se puede destruir componentes
específicos con Destroy Component.
Nodos de Colisiones
En juegos 2D, las colisiones y triggers permiten detectar interacciones físicas entre
objetos: por ejemplo, cuando el jugador choca con una pared, pisa el suelo, o recoge un
power-up. Unity distingue entre colisiones físicas (dos objetos sólidos que chocan) y triggers
(colliders marcados como disparadores, que no bloquean el movimiento pero generan
eventos de entrada/salida). Visual Scripting provee nodos de evento y utilidades para
manejar ambos casos:
● On Collision Enter 2D: evento que se activa cuando este objeto comienza a
colisionar con otro objeto (2D) que tenga un Collider2D. Por ejemplo, si el personaje
(con Rigidbody2D y Collider2D) toca una pared (Collider2D), ambos recibirán
OnCollisionEnter2D. Este nodo tiene un puerto de salida de flujo (se activa en el
momento del impacto inicial) y puertos de datos que dan información de la colisión:
típicamente un Collider u Objeto correspondiente a la otra parte que colisionó,
puntos de contacto, la fuerza del impacto (impulse), velocidad relativa,
[Link]. En Visual Scripting, usualmente nos interesa el GameObject o
Collider del otro objeto para poder identificarlo o manipularlo (por ejemplo, restar
vida si era un enemigo, detener movimiento, etc.). Podemos obtener el GameObject
a partir del Collider de salida usando nodos como [Link] o
directamente en el propio evento (algunos eventos tienen la opción Self/Other).
● On Collision Stay 2D: evento que permanece activo mientras la colisión continúa en
frames subsiguientes. Se llama en cada frame mientras los objetos sigan en
contacto. Útil, por ejemplo, para aplicar una fuerza continua mientras dos objetos
colisionan (como cinta transportadora) o para prolongar un efecto mientras el
jugador esté pisando cierta plataforma.
● On Collision Exit 2D: evento complementario que se activa cuando la colisión
termina (los objetos dejan de tocarse). Se utiliza para saber cuándo un objeto salió
de otro. Por ejemplo, detectar cuándo el jugador dejó de estar en el suelo (para
iniciar una animación de caída) o cuando sale de una zona peligrosa.
● On Trigger Enter 2D: similar a OnCollisionEnter2D, pero para coliders marcados
como Trigger. Si al menos uno de los dos colliders involucrados tiene la propiedad
Is Trigger activa, Unity no los tratará como colisión física (no rebotan ni detienen el
movimiento), sino como una superposición desencadenante. Al ocurrir esa
superposición, se llama OnTriggerEnter2D en los objetos [Link].
Este evento indica que "otro objeto entró en esta zona de trigger". Por ejemplo, un
área de daño o recoger un ítem: el jugador entra en el trigger del ítem, se activa este
evento. Los triggers se utilizan para detección de áreas, pickups, sensores, etc.,
donde no se busca una colisión física sólida sino solo detectar la presencia. Igual
que con colisiones, hay On Trigger Stay 2D (mientras permanece dentro)[Link] y
On Trigger Exit 2D (al salir)[Link].
● Configuración requerida: Para que estos eventos funcionen, es importante la
configuración de Componentes de Física 2D en los objetos:
○ Las colisiones 2D requieren que al menos uno de los objetos tenga un
Rigidbody2D (con Body Type dinámico, estático o cinemático según el caso)
y que ambos tengan Collider2D (BoxCollider2D, CircleCollider2D, etc.) con
Is Trigger desactivado (para colisiones físicas). Si ninguno tiene
Rigidbody2D (ej: dos objetos estáticos con solo colliders), no se generan
eventos de colisión.
○ Los triggers 2D requieren que Is Trigger esté activado en el collider de uno o
ambos objetos. En ese caso, no habrá colisión física (se atravesarán), pero
se generarán los eventos de OnTriggerEnter2D, [Link]. Importante:
aunque sean triggers, al menos uno de los involucrados también debe tener
un Rigidbody2D para que Unity los detecte.
● En resumen: Rigidbody2D + Collider2D → eventos de colisión; Collider2D marcado
trigger + Rigidbody2D → eventos de trigger. (Un objeto estático con collider trigger
puede detectar entrada de un Rigidbody2D que lo atraviesa, etc.)
● Información de colisión: Los nodos de colisión/trigger brindan detalles útiles. Por
ejemplo, en On Collision Enter 2D, el puerto de salida de datos Other (u Collider)
nos da el collider del otro objeto [Link], desde el cual
podemos obtener su GameObject (con Get GameObject). También disponemos de
arrays de Contacts (puntos de contacto y normales de la colisión), el vector Impulse
(fuerza de impacto) y Relative Velocity (velocidad relativa del otro objeto en el
choque)[Link]. En triggers, al no haber impacto físico, estos detalles de fuerza no
aplican, por lo que los eventos de trigger suelen proveer solo el objeto que
entró/salió. Por ejemplo, On Trigger Enter 2D da el Collider del objeto que entró al
trigger, pero no hay información de impulso ni puntos (porque no hubo colisión
física)[Link].
● Usos comunes:
○ Detección de pisos y paredes: Un personaje puede tener un
OnCollisionEnter2D en sus pies para detectar cuándo toca el suelo
(activando así la posibilidad de saltar de nuevo) y un OnCollisionExit2D para
saber cuándo lo dejó. También se pueden detectar colisiones con paredes
para impedir continuar moviendo en esa dirección.
○ Recolectables (pick-ups): Usar OnTriggerEnter2D en el objeto de item
(marcado como trigger) para detectar al jugador. En el evento, comprobar
que el objeto entrante es el jugador (por ejemplo, comparando la Tag del
GameObject con "Player") y luego ejecutar la lógica de recolección: aumentar
puntuación, reproducir sonido, y Destruir el ítem con un nodo
Destroy(GameObject).
○ Daño y enemigos: Un enemigo con collider puede usar OnCollisionEnter2D
para detectar al jugador y restarle salud. O un proyectil con Rigidbody2D usar
OnCollisionEnter2D para explotar al impactar algo.
Para manejar la lógica dentro de estos eventos, a menudo combinaremos con nodos de
lógica. Por ejemplo, dentro de OnCollisionEnter2D podríamos usar un nodo Branch (If) para
verificar alguna condición (¿el objeto colisionado tiene cierta etiqueta? ¿tiene componente
específico?), y dependiendo de eso, ejecutar distintas acciones. También es común usar
Compare Tag o [Link]: Unity Visual Scripting permite obtener la etiqueta (tag)
de un objeto con nodos como [Link] Tag y compararla con un string, o
directamente un nodo Compare Tag (GameObject, "TagName") que devuelve true/false.
Esto se usa mucho en colisiones para identificar tipos de objetos (ej. si
[Link]("Enemy") entonces…).
Nodos de UI (Interfaz de Usuario)
Visual Scripting también permite interactuar con la interfaz de usuario de Unity (basada en
UGUI, Canvas, etc.). Esto incluye responder a eventos de UI (botones, toggles, etc.) y
modificar elementos de la UI (texto, imágenes, paneles). Algunos nodos importantes de UI
son:
● On Button Click: (mencionado en Eventos). Es el nodo de evento que corresponde
al clic de un UIButton del sistema de UI. Para utilizarlo, se asegura que el objeto del
botón tenga un Script Machine (grafo) asociado, y en ese gráfico añadimos este
nodo. Podemos arrastrar la referencia del propio botón al nodo para que escuche
ese botón específico, o dejar Target = Self si el grafo está en el mismo objeto del
botón. Cuando el usuario haga click (pointer down-up) en el botón, este evento
dispara el [Link]. Dentro de la lógica, podemos entonces realizar
acciones como cambiar de escena, pausar el juego, mostrar un menú, etc.
● On Value Changed (UI): evento que se activa cuando cambia el valor de un
componente UI interactivo, por ejemplo un Toggle, un Slider o un Dropdown. Estos
nodos (ubicados en Events > GUI) permiten reaccionar a cambios en controles de la
UI sin código. Por ejemplo, On Value Changed (Toggle) se dispara cuando el
usuario marca o desmarca un checkbox, dando un valor booleano de salida (isOn).
Igualmente, un slider daría un float, etc. Son útiles para opciones o HUD interactivos.
● Set Text (Texto UI): en interfaces suele ser necesario mostrar textos dinámicamente
(puntuaciones, mensajes, temporizadores). Unity usa principalmente TextMeshPro
(TMP) para texto en UI. Con Visual Scripting, se pueden usar nodos para modificar
el texto. Por ejemplo, tras habilitar compatibilidad (añadiendo [Link] en
Node Library si no aparece por defecto), existe el nodo TextMeshPro UGUI → Set
Text, que permite asignar un string a un componente TMP
[Link]. Este nodo tiene un puerto de entrada de flujo, un puerto
de referencia al componente de texto objetivo y un puerto de dato para el string
nuevo. Podemos usarlo, por ejemplo, para actualizar un marcador: al recoger una
moneda, conectamos el flujo a Set Text y pasamos la nueva puntuación convertida a
string. Nota: Si se usa el componente de texto legacy (Text de [Link]),
también hay nodos Text → Set Text equivalentes, pero TMP ofrece más opciones y
es el estándar desde Unity 2018+.
● Set Image Fill/Color: De forma similar, existen nodos para manipular propiedades
de imágenes UI. Por ejemplo, Image → Set Color cambia el color de un Image
([Link]., para feedback de daño, parpadeo, etc.), Image → Set Fill Amount para
barras de progreso (fill amount de una Image tipo Filled). También Slider → Set
Value para modificar un slider por código, etc. En general, cualquier propiedad
pública de un componente UI es accesible: Visual Scripting genera nodos
automáticamente para métodos y propiedades de clases conocidas. Así, uno puede
buscar el nombre del componente (ej. TextMeshProUGUI, Image,
RectTransform) en el fuzzy finder para encontrar nodos disponibles.
● Canvas Group / GraphicRaycaster: Aunque más técnicos, vale mencionar que
Visual Scripting también puede controlar elementos globales de UI.
[Link] puede ajustar la transparencia de un grupo de UI,
GraphicRaycaster se puede habilitar/deshabilitar para activar o no la interacción en
un Canvas, etc.
● Instanciar/destruir UI: Se puede instanciar prefabs de UI mediante el nodo
Instantiate, igual que para objetos de juego normales, especificando como parent
un objeto del Canvas. Y removerlos con Destroy. También se puede
activar/desactivar paneles con SetActive.
En general, para usar botones y otros elementos UI con Visual Scripting, los pasos típicos
son:
1. Tener los elementos UI en una escena (por ejemplo un Canvas con botones, textos,
etc.).
2. Vincular un Script Machine (Flow Graph) a un GameObject pertinente (puede ser un
objeto vacío controlador de UI, o el mismo objeto del botón si es algo sencillo).
3. En el grafo, usar los eventos de UI (On Button Click, etc.) para saber cuándo
interactúan, y luego los nodos de acciones (por ejemplo Set Text, cargar escena,
cambiar variables) para responder a esa interacción.
Ejemplo común: Un menú principal con un botón "Jugar". Se agrega un Script Graph en el
Canvas o en el botón Jugar. En el gráfico, añadimos On Button Click (target: el botón
Jugar) y lo conectamos a un nodo [Link]("Nivel1") para cargar la
primera escena del juego cuando se haga clic.
Ejemplos prácticos en juegos 2D
A continuación se presentan ejemplos prácticos de cómo utilizar Visual Scripting en un
juego 2D para implementar tareas típicas: control de un personaje, detección de colisiones,
mostrar texto en pantalla, uso de botones de UI y temporizadores. Cada ejemplo describe
brevemente la lógica del grafo de nodos involucrado y cómo se conectan los nodos
importantes mencionados en la referencia anterior.
Control de personaje con teclado (movimiento 2D básico)
En la imagen, un grafo de Visual Scripting para mover un personaje con las teclas de flecha:
cuatro eventos On Keyboard Input (uno por tecla: izquierda, derecha, arriba, abajo)
conectados a nodos [Link] que desplazan la Nave en cada dirección. Se
usa una variable Velocidad y el nodo Per Second para lograr un movimiento uniforme
independiente del frame rate. Además, nodos Multiply ajustan el signo de la velocidad en
ejes negativos (izquierda/abajo).
Para mover un personaje 2D con el teclado, podemos usar cuatro eventos On Keyboard
Input configurados con Key = FlechaIzquierda, FlechaDerecha, FlechaArriba, FlechaAbajo,
todos con Action = Hold para que emitan flujo continuamente mientras la tecla esté
[Link]. Cada uno de estos eventos se conectará a un nodo
[Link](x,y,z) que aplique un desplazamiento pequeño al personaje en la
dirección deseada.
En el ejemplo de la Nave espacial de la imagen, se definió una variable de objeto llamada
Velocidad (en el Blackboard) para controlar la magnitud de [Link]. Su valor
inicial, digamos 5 (unidades por segundo), se utiliza para determinar qué tan rápido se
mueve la nave. Cada vez que se activa un evento de tecla, el grafo realiza lo siguiente:
● Usa un nodo Get Object Variable: Velocidad para obtener el valor actual de la
[Link].
● Pasa ese valor al nodo Per Second, que lo convierte en una distancia por
[Link]. Esto garantiza que, por ejemplo, 5 unidades/segundo se traduzcan
automáticamente a ~0.083 unidades por frame (si el juego corre a ~60 FPS),
haciendo el movimiento consistente sin importar fluctuaciones de FPS.
● El resultado de Per Second se conecta al [Link] correspondiente.
Para la flecha derecha, por ejemplo, conectaríamos el valor al puerto X positivo de
Translate (X = +VelocidadPorFrame, Y = 0), de modo que cada frame se sume un
poquito a la posición [Link]. Para la flecha izquierda, necesitamos mover en X
negativo: esto se logra pasando el valor por un nodo Multiply con -1, antes de
conectarlo a X (o directamente poniendo X = -VelocidadPorFrame)[Link]. De igual
forma, flecha arriba usa Y positivo, flecha abajo Y negativo.
● Todos los Translate también toman el puerto de flujo desde el evento de tecla
correspondiente, de modo que solo se ejecutan cuando esa tecla está en Hold. Es
decir, el On Keyboard Input (por ej. derecha) dispara flujo en cada frame mientras se
mantenga pulsada; ese flujo entra al Translate, que en consecuencia mueve la nave
ese pequeño delta en X.
● Como resultado, el jugador puede mantener pulsada una tecla y la nave se
desplazará continuamente en esa dirección hasta soltarla. Al soltar, el evento deja
de emitir flujo (Hold se detiene) y por tanto el Translate ya no se ejecuta, parando el
movimiento.
Además, en el grafo de ejemplo, se añadió lógica extra para que la nave se oriente a
izquierda o derecha según la dirección del movimiento. Esto se logra con nodos
[Link] o similares: cuando se presiona izquierda, se ejecuta un Set Local
Scale poniendo X = -1 (volteando el sprite horizontalmente)[Link]; cuando se presiona
derecha, X = 1 (escala normal) para mostrarla mirando hacia la derecha. Esa parte usa
nodos Branch para decidir el signo de la escala en base a qué tecla se pulsó, y se activa en
el flujo de los eventos de movimiento.
En resumen, este ejemplo combina nodos de evento (teclado) + variables (velocidad) +
movimiento (Translate) + operaciones matemáticas (multiplicar por -1) para lograr un
control suave del personaje. La clave es modularizar: un evento por dirección, y una
pequeña sección de grafo para mover en esa dirección. Con Visual Scripting, es fácil ajustar
la variable Velocidad desde el inspector durante pruebas (porque las Object Variables
aparecen en el objeto en el Inspector), lo cual es muy práctico para calibrar la sensación de
control.
Detección de colisiones (ejemplo de recoger un objeto)
Consideremos un escenario donde el personaje debe recoger un objeto (por ejemplo, una
moneda) al tocarlo, incrementando la puntuación y destruyendo la moneda.
Implementaremos esto usando un Trigger para la moneda:
● En Unity, marcaríamos el collider del objeto Moneda como Is Trigger (y asegurarnos
de que el jugador tiene un Rigidbody2D). Luego, en el grafo de la moneda (o en un
controlador general de ítems), usamos el evento On Trigger Enter 2D. Este evento
se activará cuando cualquier collider entre en la zona de la [Link].
● Dentro de On Trigger Enter 2D, probablemente querremos asegurarnos de que el
que entró es el Jugador y no otra cosa. Para ello, tomamos el puerto de dato del
evento, que nos da el Collider2D del objeto entrante (llamémoslo Other). Con un
nodo [Link](Other, "Player") o similar, verificamos si ese
objeto tiene la etiqueta "Player". Este nodo devuelve true/false.
● A continuación colocamos un nodo Branch (If): conectamos la salida booleana de
CompareTag al puerto de condición del Branch. Así tendremos dos ramas: True (era
el jugador) o False (era otra cosa, ignorar).
● En la rama True (jugador colisionó con la moneda), ponemos la lógica de recogida:
por ejemplo, actualizar una variable de puntuación y destruir el objeto moneda:
○ Para la puntuación, podríamos tener una Variable de Aplicación o de
Escena llamada "Score". Usamos [Link] → Get("Score"),
luego Add con el valor de puntos ([Link]., 1), y luego Set("Score") con el
resultado. Alternativamente, si tenemos un componente UI mostrando la
puntuación, podríamos incrementar y llamar a un Set Text inmediatamente
(ver siguiente ejemplo).
○ Para eliminar la moneda de la escena, usamos el nodo [Link]
sobre el objeto Self (la propia moneda). Se puede obtener el Self
(GameObject dueño del grafo) con el nodo [Link], y
alimentar eso al Destroy. O más simple, existe Destroy Self en la librería,
dependiendo de la versión.
● En la rama False del Branch (no es jugador), simplemente no hacemos nada (o
podríamos conectar a un nodo vacío o un comentario). Así, si por alguna razón otro
objeto entra (otro ítem, etc.), no se ejecuta lógica.
De este modo, cuando el jugador pase por encima de la moneda, On Trigger Enter 2D
detectará al jugador, el Branch comprobará la etiqueta y en la ruta verdadera
actualizaremos la puntuación y quitaremos la moneda. Todo sin escribir código, solo
conectando los nodos lógicos adecuados.
Para otro ejemplo, colisión con enemigo: Supongamos que el jugador tiene una vida y al
chocar con un enemigo pierde salud. En el enemigo (que tendría un collider normal, no
trigger, para posiblemente bloquear al jugador), usaríamos On Collision Enter 2D. Este
evento nos da información del jugador colisionado. Podríamos igualmente checar tag
"Player" y luego, en true, reducir una variable de vida del jugador (quizá accesible como
variable de objeto en el jugador, entonces aquí necesitaríamos acceder al objeto del jugador
– el Other collider – y mediante un [Link](OtherGameObject).Set("Vida",
nuevaVida) restarle). O más sencillo: el jugador mismo podría tener un OnCollisionEnter2D
para enemigos, pero de cualquier forma, con Visual Scripting se trata de orquestar la
detección (evento) con la reacción (cambiar variables, invocar animaciones, destruir, etc.).
Consejo: En Visual Scripting es útil aprovechar los Tags o Names de objetos para filtrar
qué se chocó, pero para proyectos más grandes podría ser preferible usar nodos Compare
Tag en lugar de comparar nombres de objeto. También se pueden usar Interfaces o Events
más avanzados, pero para principiante, el sistema de etiquetas es suficiente.
Mostrar texto en pantalla (HUD y mensajes)
Para mostrar texto en la pantalla, típicamente tendremos un Canvas UI con elementos de
texto (por ejemplo, un marcador de puntaje, o un mensaje "Game Over"). Con Visual
Scripting, podemos actualizar esos textos en tiempo real.
Ejemplo 1: Contador de puntuación. Imaginemos que tenemos un texto UI que muestra
"Score: 0" al comenzar. Cada vez que el jugador recoge una moneda (como en el ejemplo
anterior), queremos incrementar esa puntuación en pantalla.
● Primero, necesitamos una referencia al componente de texto. Si usamos
TextMeshPro, debemos asegurarnos de que Visual Scripting reconozca sus nodos
(en Unity 2022 ya debería, pero si no aparecen, en Project Settings > Visual
Scripting > Node Library se puede añadir la asamblea [Link] y
regenerar [Link]). Supongamos que tenemos un objeto ScoreText con
un componente TextMeshPro - Text (UI).
● Podemos hacer que el gráfico que maneja la puntuación (por ejemplo, un Script
Graph en un GameManager) tenga una variable de objeto referenciando ese
ScoreText (de tipo TextMeshProUGUI). Asignamos dicha referencia arrastrando el
objeto en el inspector al Blackboard.
● Ahora, cada vez que cambie la puntuación (p. ej., en el evento de recoger moneda
descrito), además de actualizar la variable Score, obtenemos el nodo Set Text del
TextMeshPro. Este nodo suele llamarse TextMeshPro [Link] y espera: flujo
de entrada, la referencia del Text (si no la tiene predefinida) y el nuevo texto (string).
Podemos construir el string concatenando "Score: " con el valor numérico de la
puntuación convertido a string (hay un nodo ToString o simplemente conectar un int
a un puerto string hace conversión implícita).
● Conectamos el flujo del evento de puntuación al Set Text. Así, cada vez que
sumemos puntos, el flujo primero suma a la variable Score y luego pasa por SetText
para actualizar la UI. El texto en pantalla cambiará inmediatamente.
● Si el texto es simplemente "Score: X", podemos usar un nodo [Link] o
concatenación (+ string) en Visual Scripting: [Link]., [Link]("Score: {0}",
scoreValue).
Ejemplo 2: Mensaje de Game Over. Supongamos que tenemos un texto "Game Over"
oculto inicialmente, que queremos mostrar cuando las vidas del jugador lleguen a 0.
● En el controlador de vida del jugador (podría ser un Script Graph en el jugador o
GameManager), tendremos una variable Vida. Cuando Vida llega a 0 (detectado por
un If: if (vida <= 0)), podemos activar la secuencia de Game Over.
● Para mostrar el texto Game Over, si el objeto de texto estaba desactivado en la
escena, podríamos usar [Link] sobre ese objeto pasándole true.
Alternativamente, si estaba con alfa 0, podríamos cambiar su alfa a 1 con
[Link]. Pero lo más sencillo: diseñar el Canvas con el texto oculto
(SetActive = false) y en Visual Scripting hacer un SetActive(GameOverText, true)
cuando corresponda.
● También podríamos reproducir una animación de UI o pausar el juego
([Link] = 0 usando Time → Set Time Scale node).
● Para reiniciar, un botón "Reintentar" podría estar presente y visible tras Game Over,
usando su On Click evento para recargar la escena con [Link]
node.
Nota: Muchos nodos de UI corresponden directamente a métodos de clases de
[Link] o TMPro. Por ejemplo, SetActive corresponde a [Link],
SetText a [Link] property, LoadScene a [Link], etc.
Visual Scripting expone la mayoría de la API de Unity. Si no encuentra un nodo específico,
verifique que la Type Options en Project Settings incluyan esa clase/namespace.
En resumen, para mostrar texto en pantalla dinámicamente:
1. Tener el elemento de texto en la escena (UI).
2. Obtener acceso a él en Visual Scripting (variable arrastrada o usando un nodo Find
si es necesario, aunque es mejor referenciar directamente).
3. Usar el nodo de Set Text apropiado para cambiar su contenido cuando se requiera,
alimentándolo con la cadena deseada.
Y si hace falta, controlar su visibilidad con SetActive o similares.
Uso de botones de interfaz (UI) para interacciones
Los botones en la UI son fundamentales para menús, opciones y ciertas acciones en
juegos móviles o de PC (ej: abrir inventario, pausar, disparar en móviles, etc.). Unity Visual
Scripting permite manejarlos sin código mediante los eventos GUI. Veamos un ejemplo
sencillo: un botón de "Pausar/Continuar".
● En la escena tenemos un Button UI llamado PauseButton. Le hemos asignado un
ícono o texto (Pausa/Play).
● Creamos un Script Graph en un objeto controlador (por ejemplo un GameManager) o
en el mismo PauseButton objeto.
● Añadimos el nodo On Button Click y, en el Inspector del nodo, establecemos Target
= PauseButton (podemos arrastrar el objeto PauseButton hasta ese campo). De esta
manera, el evento se vincula a ese botón específico.
● Ahora, cada vez que se pulse el botón, el flujo saldrá de On Button Click. Podemos
alternar un estado de pausa. Para ello, podemos usar una Variable booleana
isPaused en el Graph o Object. Inicialmente false.
● Del On Button Click, llevamos el flujo a un nodo Toggle Value o simplemente a una
secuencia: un Branch que cheque isPaused:
○ Si no estaba pausado (False), entonces al pulsar queremos pausar: poner
[Link] = 0 (nodo Time → Set Time Scale 0), mostrar un menú de
pausa quizás (SetActive(menuPausa, true)), y marcar isPaused = true
(Set Variable isPaused = true).
○ Si ya estaba pausado (True), entonces al pulsar queremos reanudar:
[Link] = 1, ocultar menú de pausa, y isPaused = false.
● Para cambiar el icono o texto del botón (por ejemplo de "Pausa" a "Play"), podríamos
también usar un Set Text o cambiar la imagen del botón. Esto se haría dentro de las
ramas del Branch: cuando pausamos, quizá cambiar el texto a "Continuar", y
viceversa.
Este patrón cubre la mayoría de usos de botones: se captura el click y luego se realiza la
lógica deseada. Otros ejemplos:
● Botón "Salir": On Button Click -> nodo [Link]() (hay nodo para eso) para
cerrar la aplicación.
● Botón "Disparar" en móvil: On Button Click -> instanciar un proyectil (usando
Instantiate nodo con un prefab de bala) desde la posición del jugador.
● Botones de nivel: On Button Click (Nivel 2) -> LoadScene("Nivel2").
● Botones de configuración: On Toggle Changed (Fullscreen) ->
[Link] con el bool que viene de toggle.
En todos estos, Visual Scripting actúa como el puente entre la UI y la acción del juego, sin
necesidad de escribir los event handlers manualmente.
Temporizadores y retrasos (esperas)
Los temporizadores se utilizan para acciones diferidas en el tiempo o repetitivas (ejemplo:
una bomba que explota tras 3 segundos, un power-up que dura 10 segundos, un mensaje
que parpadea cada medio segundo, etc.). Unity Visual Scripting tiene nodos dedicados para
manejar el tiempo:
● Wait For Seconds: es un nodo que pausa el flujo de ejecución durante un número
de segundos especificado antes de continuar. Por ejemplo, se puede usar en una
secuencia para crear un retraso: On Start -> (alguna acción inicial) ->
Wait For Seconds(3) -> (acción después de 3 segundos). Durante la
espera, el flujo queda "dormido" y luego continú[Link]. Internamente,
esto utiliza corrutinas de Unity. Importante: Para que los nodos Wait funcionen, el
evento inicial que inicia la secuencia debe estar marcado como Coroutine en el
Graph [Link]. Por ejemplo, si usamos Wait dentro de la lógica
de un On Start, debemos seleccionar el nodo On Start y activar la casilla Coroutine.
Al hacerlo, el nodo de evento mostrará un ícono especial (dos flechas circulares)
indicando que correrá como corrutina y así los waits serán válidos. Si olvidamos este
paso, al ejecutar obtendríamos un error de "can only be triggered in a
coroutine"[Link].
Usos típicos: temporizador de explosión – Wait 5s luego Destroy Self; reaparecer
un enemigo – Wait X segundos luego Instantiate enemigo; cadena de eventos con
delay – por ejemplo, flash de daño: activar un efecto, Wait 0.1s, desactivar efecto
(para parpadeo).
● Wait Until / Wait While: nodos que esperan hasta que se cumpla una condición, o
mientras se cumpla una condición, respectivamente. Por ejemplo, Wait
Until(condition) detiene el flujo hasta que la condición booleana pase a
[Link]. Esto se puede usar para esperar hasta que cierta variable
cambie (ej: esperar hasta que enemigosRestantes == 0 para terminar un nivel).
Wait While(condition) hará lo contrario: pausa el flujo mientras la condición sea
true, y continúa cuando sea [Link]. Son útiles para sincronizar
eventos con estados del juego sin tener que chequear constantemente en Update.
● Wait For Frames: hay variantes como Wait for End of Frame o Wait for Next
Frame, que postergan la ejecución al final del frame actual o al siguiente
[Link]. Son menos comunes en lógica de gameplay, pero pueden
servir para secuenciar cosas que necesitan esperar que termine el frame (por
ejemplo, para asegurarse de que ciertas físicas se hayan resuelto).
● Timer: Visual Scripting incluye un nodo más complejo llamado Timer, que
implementa un temporizador con funcionalidad de pausa y reanudar. El nodo Timer
tiene un puerto de entrada Start (inicia el conteo), puertos Pause, Resume, Toggle
(pausa/continúa), y salidas de flujo Started, Tick,
[Link]. También provee puertos de datos
Elapsed, Remaining (tiempo transcurrido y restante) y sus versiones en porcentaje
(0 a 1)[Link], muy útiles para, por ejemplo, actualizar una barra de
progreso mientras dura el temporizador. Se puede usar Timer para cosas como:
temporizador de nivel (cuenta regresiva de 60s), cooldowns de habilidades (no
permitir usar una habilidad hasta que el Timer Completed tras X segundos), etc.
Ejemplo: Supongamos un power-up que dura 10 segundos. Al recogerlo, activamos
Timer (Start con Duration = 10). Cada frame mientras activo, Tick sale del Timer,
podríamos usar Remaining% para llenar una barra UI mostrando cuánto
[Link]. Al finalizar, Completed se activa, donde
pondríamos la lógica de fin del power-up (revertir efectos). Timer es conveniente
porque incorpora toda esa lógica en un solo nodo.
● Cooldown: otro nodo relacionado es Cooldown, que implementa un patrón de
cooldown reutilizable. Tiene un puerto de entrada que puedes pasar antes de
ejecutar cierta acción; si el cooldown está listo, dará flujo por Ready y comenzará el
cooldown, si no, saldrá por Not [Link]. También tiene un
Completed cuando el cooldown termina, y Tick con similar información de
[Link]. Podría servir por ejemplo para limitar la frecuencia de
disparo: al presionar botón disparar, pasar por Cooldown (duración = 0.5s); la
primera vez estará Ready (dispara y comienza cooldown), si el jugador pulsa de
nuevo antes de 0.5s saldrá por Not Ready (ignorar entrada), etc. Cuando se
cumplen 0.5s, Completed indica que ya se puede volver a disparar.
Ejemplo práctico de temporizador: Supongamos un juego estilo arena donde tras 30
segundos aparece un jefe final. Podemos implementar un temporizador global:
● En On Start del nivel, configuramos un Timer Duration = 30, y marcamos el On Start
como Coroutine (por seguridad, aunque Timer tal vez no lo requiera al no ser un Wait
sino evento en sí mismo, pero en general se puede).
● Conectamos On Start → [Link]. Cuando el Timer termine, se activará
Completed, que conectamos a la lógica de spawn del jefe (por ejemplo,
Instantiate(BossPrefab) en la posición deseada).
● Mientras tanto, podríamos conectar el Tick del Timer a actualizar un texto UI
"Tiempo: X seg" usando el Remaining del Timer formateado a entero, para que vaya
mostrando la cuenta regresiva. El Tick se ejecuta cada frame, así que cada frame
actualizamos el texto con ceil(Remaining) o similar.
● Si quisiéramos permitir pausar este temporizador global cuando el jugador abre el
menú, podríamos llamar [Link] al pausar y [Link] al continuar (lo cual
detiene/continúa tanto la cuenta interna como los Ticks). Alternativamente,
podríamos haber usado simplemente timeScale = 0 global, pero Timer ofrece control
fino en caso de que solo queramos pausar algunos temporizadores específicos.
Con Wait For Seconds podríamos lograr lo mismo de manera más simple: On Start -> Wait
30s -> spawn boss. Sin embargo, si quisiéramos pausar a mitad, un Wait en coroutine no
obedece el timeScale (a menos que use WaitForSecondsRealtime). El Timer en cambio
puede configurarse si toma o no en cuenta la escala de tiempo (Unscaled
opción)[Link]. Son matices avanzados, pero importantes en diseño de juego.
En conclusión, Visual Scripting ofrece varias formas de manejar el tiempo:
● Wait nodes para secuencias lineales con demoras simples.
● Timer/Cooldown nodes para temporizadores interactivos, que dan más control
(pausar, porcentaje transcurrido, etc.).
● Uso explícito de [Link] en Update para contadores manuales (por ejemplo,
incrementando una variable acumulada y comparando).
● Uso de InvokeRepeating o similares no está directamente disponible como nodo,
pero se pueden replicar comportamientos repetidos con combinaciones de Wait
dentro de bucles o simplemente usando Update + contadores.
Elija la herramienta según la necesidad. Para principiantes, Wait For Seconds es muy
intuitivo para cosas sencillas (pero recordar marcar Coroutine!), mientras que Timer puede
parecer complejo pero resuelve casos comunes de cuenta regresiva y cooldown sin mucho
esfuerzo manual.
Recursos y documentación
Para profundizar en Unity Visual Scripting, se recomiendan las siguientes fuentes oficiales y
material de apoyo:
● Documentación oficial de Unity – Sección de Visual Scripting en el Manual de
Unity (en inglés): aquí encontrará detalles de todos los nodos, configuraciones y
consejos [Link]. Es una referencia exhaustiva para resolver dudas
específicas sobre unidades (nodos) y el sistema en distintas versiones de Unity.
● Unity Learn – Curso de Introducción al Visual Scripting – Un curso oficial
(disponible en Unity Learn) que guía paso a paso por los conceptos básicos de
Visual Scripting, ideal para [Link]. Incluye tutoriales prácticos,
ejercicios y ejemplos interactivos para asentar los conocimientos.
● Tutoriales en español (CIPSA, blog educativo) – Serie "Programación visual para
Unity" por Ángel Aguinaga, que explica con ejemplos claros y video tutoriales el uso
de Visual Scripting en [Link]. Especialmente útiles son los capítulos donde
aborda desde los fundamentos (diagramas y nodos) hasta casos prácticos como
control de teclado, colisiones y subgráficos, en contexto de desarrollo de
videojuegos 2D.