Eventos
La vida de una partícula tiene momentos obvios: nace, puede chocar con algo, muere, se destruye. Sin Eventos, lo único que hace el plugin en cada uno de esos momentos es lo predeterminado — emitir visuales al nacer, animar los gráficos a lo largo de la vida, destruir cuando termina el tiempo de vida. Los Eventos te permiten adjuntar más comportamiento a cada uno de esos momentos. Rebotar en la pared en lugar de atravesarla. Generar un segundo emisor cuando muere el primero. Ejecutar un breve script Luau que muta la partícula, reproduce un sonido, actualiza el estado del juego.
Los Eventos son la forma en que el plugin conecta el comportamiento de las partículas con la lógica del juego sin que tengas que escribir a mano una conexión RenderStepped por cada emisor.
Los cuatro tipos de evento
Sección titulada «Los cuatro tipos de evento»Cada emisor expone hasta cuatro tipos de evento en su panel de propiedades. Cuáles están disponibles depende del tipo — los tipos espaciales (Part, Attachment, Model) obtienen los cuatro; los tipos no espaciales (Beam, PointLight, Trail/TrailEmitter, Highlight, los tipos de espacio de pantalla, ImageLabel) saltan OnHit porque no tienen colisiones.
| Evento | Se dispara cuando | Disponible en |
|---|---|---|
| OnEmit | Un clon de partícula acaba de aparecer y está entrando en el bucle de simulación | Todos los tipos |
| OnHit | Un raycast desde la posición de la partícula en el fotograma anterior hasta su posición actual impacta con una superficie de colisión | Part, Attachment, Model |
| OnDeath | El Lifetime de la partícula acaba de expirar (antes de que comience cualquier desvanecimiento de Linger) | Todos los tipos |
| OnDestruction | El visual está a punto de ser destruido (después de Linger, si lo hay) | Todos los tipos |
Cada evento del panel está colapsado por defecto con un interruptor Enabled. Apagado no cuesta nada — el entorno de ejecución no paga ninguna comprobación por fotograma, el sistema se mantiene en silencio. Encendido expande la fila de configuración para ese evento.
Qué puede hacer cada evento
Sección titulada «Qué puede hacer cada evento»Cada evento tiene la misma forma de autoría. Una vez habilitado, puedes configurar cualquier combinación de:
- Emit — elige otro emisor (transformado o nativo) para generar cuando se dispare el evento. Habitual: OnDeath emite una explosión, OnHit emite una ráfaga de chispas.
- Mode — controla dónde aterriza la emisión encadenada. Cuatro valores:
- AtPosition — en la posición mundial del evento (el punto de aparición para OnEmit; el punto de impacto para OnHit; la posición de muerte para OnDeath / OnDestruction). Para OnHit en concreto, la posición de aparición se empuja ligeramente a lo largo de la normal de la superficie para que la emisión encadenada no vuelva a colisionar inmediatamente con la misma superficie.
- AtSource — en la posición actual del emisor de origen. Para emisores de larga vida que se han movido, esto es «dónde está ahora quien genera» en lugar de «dónde estaba esta partícula».
- AtTarget — clona el emisor elegido en su propia posición de autoría (el predeterminado para objetivos encadenados no espaciales).
- AtCFrame — propaga el
CFramecompleto de la partícula de origen (posición y rotación) a la emisión encadenada. Útil cuando el emisor encadenado debe coincidir con la orientación del que gira — una bola de fuego que rueda y genera rastros de chispas orientados en lugar de ráfagas radiales.
- Script — activa para adjuntar un módulo Luau. El plugin genera un script de partida con la API completa del payload del evento documentada en comentarios. Edítalo mediante el botón Edit Script del panel. Útil para efectos secundarios de lógica de juego: reproducir un sonido en el impacto, registrar daño, actualizar un objetivo de misión al morir.
- Chain depth — un control deslizante de 1 a 32 que limita cuántos saltos de eventos anidados pueden dispararse desde este. El valor por defecto es
4. Si un evento encadenado intenta emitir más profundamente que el límite, la emisión se descarta silenciosamente (y aparece una advertencia una vez por segundo en Output). El techo absoluto de 32 evita la recursión descontrolada. - Reset Event — borra la configuración por evento y cualquier script adjunto. Pide confirmación antes de destruir.
El selector de Emit y el interruptor de Script son independientes — puedes tener uno sin el otro, o ambos. Un evento con solo un Emit dispara un efecto de partícula encadenado sin lógica adicional; uno con solo un Script ejecuta tu código sin generar nada; uno con ambos hace ambas cosas.
OnHit, en detalle
Sección titulada «OnHit, en detalle»OnHit es el más rico en funciones de los cuatro porque las colisiones son eventos físicos a los que el plugin puede reaccionar, no solo observar.
Los modos de Collide
Sección titulada «Los modos de Collide»Una vez que habilitas OnHit, aparece un menú desplegable Collide con cuatro opciones. Esta es la característica destacada.
Off (el predeterminado) — atraviesa. OnHit sigue disparándose (así que las emisiones encadenadas y los scripts se ejecutan), pero el movimiento de la partícula no se ve afectado. La partícula continúa a través de la superficie como si no estuviera ahí. Úsalo para efectos de impacto puramente cosméticos: polvo de pisadas que no afecta a la bala, chispas de rebote donde la bala penetra de todos modos.
Kill — fija el visual en la posición de impacto y luego destruye la partícula. OnDeath se dispara antes de la destrucción (a menos que lo suprimas en un script). Si Linger está activado, el visual permanece visible durante esa ventana de linger antes de ser destruido. El comportamiento clásico «la bala impacta en la pared, desaparece al impactar».
Stop — fija en la posición de impacto y congela todo el movimiento. La partícula envejece de forma natural, disparando OnDeath al final del tiempo de vida como siempre. Se usa para partículas que deben pegarse — un dardo incrustado en una pared, un sello mágico que se adhiere al contacto, una flecha que aterriza y se queda. Mientras está pegada, los raycasts posteriores no vuelven a disparar OnHit (la partícula está en reposo).
Bounce — reflexión realista. Tres escalares ajustables se vuelven editables cuando se elige este modo:
- Bounciness (0 a 1, predeterminado
0.7) — restitución.0es sin rebote (actúa como Stop);1es una reflexión perfecta de espejo. La mayoría de los objetos naturales rebotan entre0.3y0.7. - Friction (0 a 1, predeterminado
0.2) — amortiguación tangencial. Reduce la velocidad lateral por rebote. Valores más altos hacen que cada rebote sucesivo se ralentice visiblemente;0deja que una partícula se deslice eternamente a lo largo de una superficie. - Spin (0 a 2, predeterminado
0.5) — impulso angular en la colisión. El producto cruzado de la normal del impacto con la velocidad tangencial alimenta el giro rotacional de la partícula, de modo que los rebotes que ruedan hacia adelante caen rodando de forma natural por las pendientes.
El modelo de Bounce divide la velocidad de la partícula en componentes normal y tangencial, aplica la física y reescribe la nueva velocidad. Los rebotes sucesivos pierden energía a través tanto de Bounciness como de Friction.
Dos excepciones de compatibilidad que conviene conocer:
InvertMotion = truedegrada silenciosamente Bounce a Kill. La ruta de movimiento inverso usa una trayectoria de CFrame en caché que no puede adaptarse a la redirección en pleno vuelo, así que el motor no puede respetar Bounce ahí. Diseña tus configuraciones de rebote conInvertMotion = false.- El modo Animate omite Kill / Stop / Bounce. El modo Animate reproduce los gráficos directamente sobre la instancia de origen, sin clones que redirigir. Los modos de colisión de OnHit solo se aplican significativamente al modo Emit, donde cada partícula es su propio clon.
Filter — grupos de colisión y listas de exclusión
Sección titulada «Filter — grupos de colisión y listas de exclusión»Debajo del menú desplegable Collide, una fila Filter te permite delimitar qué superficies registran impactos:
- Collision Group — elige un nombre de grupo de colisión de Roblox (los mismos grupos que configuras en el editor de Collision Groups de Studio). Si se establece, solo las superficies de ese grupo disparan OnHit. Déjalo vacío para hacer raycast contra todo.
- Exclude List — abre el selector y selecciona cualquier número de instancias. Sus árboles descendientes completos se filtran del raycast. Útil para evitar impactos sobre uno mismo (excluye al personaje que disparó el proyectil) o para que los proyectiles atraviesen NPCs amistosos.
Limitación del raycast
Sección titulada «Limitación del raycast»Un control deslizante HitCheckInterval (0 a 0,5 segundos, predeterminado 0) controla la frecuencia del raycast independientemente del modo Collide. 0 hace raycast cada fotograma de Heartbeat; los valores más altos saltan fotogramas entre comprobaciones para ahorrar CPU en emisores de alta tasa, a costa de potencialmente atravesar superficies delgadas. La mayoría de la autoría debería dejar esto en 0; recurre a él solo si estás emitiendo cientos de partículas físicamente relevantes por segundo y el profiler muestra que los raycasts dominan.
OnDeath frente a OnDestruction
Sección titulada «OnDeath frente a OnDestruction»Dos eventos cercanos al final parecen similares pero se disparan en momentos diferentes:
- OnDeath — se dispara cuando
Lifetimeexpira. Antes de que comience cualquier desvanecimiento deLinger. Los últimos valores animados de la partícula siguen siendo los del final de sus gráficos de vida. - OnDestruction — se dispara justo antes de que se destruya la instancia visual. Después de que
Lingerse complete (o inmediatamente, siPartLife = 0).
Si tu emisor tiene PartLife = 0 (sin linger), los dos eventos se disparan en fotogramas consecutivos — OnDeath primero, luego OnDestruction una vez que el motor mata el visual. Con un PartLife distinto de cero, OnDestruction se dispara más tarde, después del desvanecimiento visible.
Elige OnDeath para efectos del tipo «esta partícula se acaba de agotar — genera lo siguiente». Elige OnDestruction para «esta partícula por fin se ha ido — limpia el estado del juego».
Trust — el límite de seguridad para scripts importados
Sección titulada «Trust — el límite de seguridad para scripts importados»El plugin distingue entre los scripts de evento que creaste localmente y los scripts que llegaron a tu proyecto desde otro lugar (un modelo de Toolbox, una copia en la nube, una configuración compartida). Los scripts importados se marcan como untrusted por defecto y no se ejecutan, incluso si su evento está Enabled.
Cuando seleccionas un emisor con un evento untrusted, el panel muestra una insignia dorada «Untrusted — revisa el script, luego haz clic en Trust antes de que esto pueda ejecutarse». El flujo:
- Haz clic en Edit Script para abrir el código Luau en el Script Editor de Studio.
- Léelo. Asegúrate de que hace lo que dice hacer.
- Haz clic en Trust Script (la insignia se convierte en un botón).
- La marca se borra y el evento puede ejecutarse.
Habilitar el evento no implica confiar en él. Siempre tienes que inspeccionar la fuente primero. Si eliminas y vuelves a importar el asset, la nueva copia es independientemente untrusted.
La razón: código Luau arbitrario de otro lugar no debería ejecutarse sin supervisión en tu proyecto. Trust es por asset, por importación y por evento. Reutilizar una configuración que escribiste tú mismo no vuelve a activar esto — solo lo hacen las importaciones externas.
Dónde aparecen los eventos en el panel
Sección titulada «Dónde aparecen los eventos en el panel»El panel de propiedades de cada tipo de emisor tiene una sección colapsable Events, normalmente cerca de la parte inferior del panel, debajo de las propiedades específicas del tipo. Dentro hay una fila por cada tipo de evento aplicable — OnEmit, OnHit (si el tipo lo admite), OnDeath, OnDestruction.
Cada fila es un interruptor en la parte superior. Apagado muestra solo el interruptor y el nombre del evento. Encendido expande la fila para mostrar Description / selector Emit / menú desplegable Mode / interruptor Script / control deslizante Chain depth / (solo OnHit) controles de Collide / (si untrusted) insignia Trust / botón Reset.
La edición multi-selección funciona como en el resto del panel — si dos emisores tienen valores de Mode diferentes, el menú desplegable muestra un «~» triestado para que no sobrescribas por accidente. Las ediciones se propagan a cada emisor seleccionado.
La API en tiempo de ejecución — Particle:EnableEmitAt
Sección titulada «La API en tiempo de ejecución — Particle:EnableEmitAt»Para autoría desde el lado del script, la API pública en tiempo de ejecución gana un nuevo método:
Part_Icles:EnableEmitAt(item, originCFrame, emitCtx?)Esto dispara item (un emisor transformado, un PE nativo o un Trail) en un CFrame mundial específico, anulando la posición de autoría del objetivo. El emitCtx opcional lleva metadatos de seguimiento de cadena (profundidad, id de cadena padre) — los Eventos lo usan internamente para hacer cumplir el límite de Chain depth y para mantener las emisiones anidadas asociadas con la partícula de origen.
Cuándo recurrir a :EnableEmitAt:
- Estás escribiendo un script de evento y necesitas generar un emisor en una posición que calculaste dinámicamente — no el Link de autoría ni la posición por defecto, sino un punto calculado en tiempo de ejecución.
- Quieres la aplicación del límite de cadena y la propagación estándar del id de cadena, que
:Emity:EnableEmitno proporcionan por sí solas.
Para el caso común de «disparar este emisor en su posición de autoría», sigue usando :EnableEmit(item) o :AbsoluteEmit(item) — son más cortos y manejan el caso común directamente.
Un ejemplo trabajado: bola de fuego rebotadora
Sección titulada «Un ejemplo trabajado: bola de fuego rebotadora»Una configuración canónica impulsada por Eventos:
-
Crea un emisor Fireball de tipo Part. Lifetime 3 seg, Speed 20 studs/seg,
PartLife = 0.5para un desvanecimiento, gráfico de color rojo. -
Evento OnEmit — Mode =
AtCFrame, Emit = un emisorSparkTrailde tipo Attachment separado. Cada ráfaga de bola de fuego emite un rastro de chispas orientado para coincidir con la pose de la bola de fuego en el momento de aparición. -
Evento OnHit — Collide =
Bounce, Bounciness0.8, Friction0.3, Spin0.7. Sin Emit configurado en este evento. La bola de fuego rebota de forma realista en las paredes; su rotación cae rodando con cada rebote. -
Evento OnDeath — Mode =
AtPosition, Emit = un emisorExplosionde tipo Part. Cuando expira el tiempo de vida de 3 segundos de la bola de fuego, una explosión estalla en su posición final. -
Evento OnDestruction — Mode =
AtPosition, Emit = un emisorLingeringGlowde tipo PointLight. Después de que el desvanecimiento de 0,5 seg se complete y el visual de la bola de fuego sea destruido, un lento pulso de PointLight marca el sitio durante otro segundo o dos.
Esa es la cadena completa. Sin scripts Luau personalizados — cada comportamiento proviene del selector de Emit + el menú desplegable de Mode + el modo Bounce. Si quieres un sonido de impacto al rebotar, adjunta un pequeño Script a OnHit que llame a SoundService en la posición de impacto.
Vale la pena saber
Sección titulada «Vale la pena saber»Algunas peculiaridades y trampas.
Chain depth tiene un tope de 32 y un valor por defecto de 4. Una cadena de longitud 4 cubre la mayor parte de la autoría: bola de fuego → rastro de chispas → chispa individual → resplandor posterior. Más allá, las cadenas complejas empiezan a chocar con los límites silenciosamente. Sube el control deslizante en el evento específico si necesitas más profundidad, pero piensa bien si la estructura puede aplanarse primero.
Habilitar un evento no le otorga Trust automáticamente a su script. Una confusión común: pones Enabled en on, esperas que el script se ejecute, y no lo hace. Comprueba si hay una insignia dorada de Untrusted. Trust es un segundo clic explícito.
InvertMotion y el modo Animate desactivan Bounce. Bounce necesita una trayectoria mutable por fotograma, que ninguno de esos modos proporciona. El entorno de ejecución degrada silenciosamente a Kill (para InvertMotion) o trata Collide como Off (para el modo Animate).
OnHit no vuelve a dispararse en la misma superficie. Una vez que se registra un impacto, la superficie se mantiene retenida hasta que la partícula se separa (se aleja del contacto); solo entonces OnHit se vuelve a armar. Así que el modo Off no satura OnHit por cada fotograma que la partícula está dentro de una pared — se dispara una vez, al entrar.
Los eventos se disparan incluso si el selector de Emit está vacío. Si has habilitado un evento puramente por su Script, no necesitas un Emit. El script se ejecuta; no se encadena nada.
Qué viene a continuación
Sección titulada «Qué viene a continuación»Los Eventos son la capa del plugin para «qué ocurre cuando». El siguiente capítulo — Por Qué las Partículas de Malla Vencen al ParticleEmitter Nativo — sale de la autoría y entra en la arquitectura: cómo el bucle caliente por partícula del plugin consigue superar a un sistema de sprite quad en el mismo hardware.