Ejemplos
Los capítulos anteriores cubrieron la superficie de la API — Lifecycle para :Activate / :Deactivate, Emission para los seis despachadores, Per-type Methods para llamadas directas, Texture Pinning para el precalentamiento de assets. Este capítulo recorre cuatro casos de uso canónicos de principio a fin — el tipo de problemas que la mayoría de los juegos encuentran, con ejemplos de scripts completos que puedes adaptar.
Patrón 1: Tajo de espada — chispas al atacar
Sección titulada «Patrón 1: Tajo de espada — chispas al atacar»Tienes una espada en tu juego y quieres que salten chispas de la punta cuando el jugador ataque. La espada tiene un Attachment en su punta, y has transformado ese Attachment como emisor de tipo Beam (a través del panel del plugin).
El disparador se ejecuta en un evento de ataque desde tu script de espada. La emisión es breve — unas pocas chispas, sin continuación.
local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))Part_Icles:Activate()
local swordSpark = workspace.Sword.SparkAttachment.SparkBeam -- transformed Beam
-- Set timing onceswordSpark:SetAttribute("EmitCount", 1)swordSpark:SetAttribute("EmitDuration", 0.15)
-- Connect to swing eventsword.OnSwing:Connect(function() Part_Icles:EnableEmit(swordSpark)end):EnableEmit lee los atributos y produce una ráfaga inicial, luego emisión continua durante 0.15 segundos. Los gráficos animados del Beam se reproducen durante la vida útil de cada emisión, la animación de ataque de la espada se reproduce, y las chispas se desplazan naturalmente porque los attachments del Beam están dentro del modelo de la espada.
Si quisieras una única chispa por ataque en lugar de un flujo continuo, usa :Emit — ignora EmitCount / EmitDuration por completo y dispara una sola ráfaga:
sword.OnSwing:Connect(function() Part_Icles:Emit(swordSpark)end):Emit produce una ráfaga y se detiene ahí.
Patrón 2: Bola de fuego — clonar desde ReplicatedStorage con ráfaga temporizada
Sección titulada «Patrón 2: Bola de fuego — clonar desde ReplicatedStorage con ráfaga temporizada»Tienes un efecto de bola de fuego creado en ReplicatedStorage. Es un Model que contiene una esfera con textura, una cola de tipo Beam y un PointLight — todos hijos transformados, listos para emitir juntos como una partícula compuesta anidada.
Cuando el jugador lanza un hechizo de bola de fuego, clonas el modelo, lo posicionas en el origen del hechizo, activas la emisión y limpias después.
Si la bola de fuego usa texturas que el jugador no ha visto antes en esta sesión, también llama a :Preload en la plantilla una vez al inicio del juego para que el primer lanzamiento no se congele esperando los bytes del asset.
local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))Part_Icles:Activate()
local fireballTemplate = game.ReplicatedStorage.FireballVFX -- Model with transformed children
local function castFireball(originPosition) local fireball = fireballTemplate:Clone() fireball:PivotTo(CFrame.new(originPosition)) fireball.Parent = workspace.Effects -- a Folder for transient effects
Part_Icles:AbsoluteEmit(fireball)
-- Clean up after the longest-lived emission finishes task.delay(3, function() fireball:Destroy() end)end
-- Trigger from your spell logicspellCast.OnFireball:Connect(castFireball):AbsoluteEmit recorre el Model clonado de la bola de fuego, encuentra cada hijo transformado (esfera, beam, luz) y activa su emisión en conjunto. Cada hijo usa sus propios atributos EmitCount / EmitDuration creados — los que se establecieron en él en Studio al ajustar el efecto. El Model padre no tiene ningún papel más allá de agrupar; :AbsoluteEmit no propaga atributos del contenedor hacia abajo. Así que ajusta los tiempos por hijo en el momento de la autoría, luego activa todo el conjunto con una sola llamada.
El task.delay(3) de limpieza es una red de seguridad. Elige la duración basándote en el EmitDuration del hijo de mayor duración más el Lifetime de sus partículas — tres segundos está cómodamente por encima de la mayoría de los efectos creados.
Si prefieres que la bola de fuego permanezca activa hasta que tu lógica de hechizo decida que ha terminado — por ejemplo, una bola de fuego guiada que sigue el cursor durante una duración variable — guarda una referencia y desactívala explícitamente:
local fireball = fireballTemplate:Clone()fireball.Parent = workspace.EffectsPart_Icles:AbsoluteEmit(fireball)
-- Later, when the spell ends:for _, item in fireball:GetDescendants() do if item:GetAttribute("Transformed") then Part_Icles:Disable(item) endendtask.wait(2) -- let in-flight particles finishfireball:Destroy()Patrón 3: Emisión solo en pantalla para optimizar el rendimiento
Sección titulada «Patrón 3: Emisión solo en pantalla para optimizar el rendimiento»Algunos efectos son suficientemente costosos como para que solo quieras ejecutarlos cuando el jugador pueda verlos. Un “aura mágica” pasiva que emite constantemente en cada NPC del mundo se acumula rápidamente — veinte NPCs × 30 partículas por segundo × en todos los clientes se acerca rápidamente al presupuesto de partículas del motor.
Solución: condicionar la emisión a una verificación de distancia o de visibilidad en pantalla, sondeada por NPC a baja frecuencia.
local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))Part_Icles:Activate()
local camera = workspace.CurrentCameralocal emissionDistance = 80 -- studslocal pollInterval = 0.25
local function trackNPC(npc) local emitter = npc:FindFirstChild("AuraEmitter") -- transformed Part-Icle if not emitter then return end
local emitting = false while npc.Parent do local distance = (camera.CFrame.Position - npc.HumanoidRootPart.Position).Magnitude local shouldEmit = distance < emissionDistance
if shouldEmit and not emitting then Part_Icles:EnableEmit(emitter) emitting = true elseif not shouldEmit and emitting then Part_Icles:Disable(emitter) emitting = false end
task.wait(pollInterval) end
-- NPC despawned; ensure emitter is off if emitting then Part_Icles:Disable(emitter) endend
-- Spawn-trackingfor _, npc in workspace.NPCs:GetChildren() do task.spawn(trackNPC, npc)endworkspace.NPCs.ChildAdded:Connect(function(npc) task.spawn(trackNPC, npc)end)El intervalo de sondeo de 0.25 segundos es un equilibrio — demasiado frecuente y el propio filtrado se convierte en el costo; demasiado infrecuente y la emisión se retrasa notablemente respecto al movimiento de la cámara. En la mayoría de los casos, 0.25 segundos es invisible para el jugador y suficientemente económico.
Para un culling más sofisticado (verificación de frustum en lugar de distancia), usa Camera:WorldToViewportPoint:
local viewportPoint, onScreen = camera:WorldToViewportPoint(npc.HumanoidRootPart.Position)local shouldEmit = onScreen and viewportPoint.Z > 0 -- Z > 0 means in front of cameraEsto cubre el caso en que un NPC está cerca de la cámara pero detrás de ella (un aura de 360° visible desde lejos normalmente no sería eliminada por una distancia simple).
Patrón 4: :AbsoluteEmit recursivo en un rig de VFX complejo
Sección titulada «Patrón 4: :AbsoluteEmit recursivo en un rig de VFX complejo»Para efectos elaborados — por ejemplo, una explosión que sacude el entorno con múltiples componentes emisores — un único :AbsoluteEmit en la raíz del rig te ahorra tener que encadenar disparadores individuales.
local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))Part_Icles:Activate()
local explosionRig = game.ReplicatedStorage.ExplosionVFX -- Folder
-- Folder contents:-- ExplosionVFX/-- CoreFlash (transformed Part — bright flash)-- Shockwave (transformed Beam — outward ring)-- Debris (transformed Part — scattered chunks)-- Smoke (transformed Part — lingering cloud)-- Light (transformed PointLight — illumination)-- ScreenColor (transformed ColorCorrection — brief tint)-- ScreenBlur (transformed Blur — concussion blur)
local function triggerExplosion(position) local effect = explosionRig:Clone() effect:PivotTo(CFrame.new(position)) effect.Parent = workspace.Effects
Part_Icles:AbsoluteEmit(effect)
task.delay(5, function() effect:Destroy() end)end
-- Hook into your explosion eventexplosionEvent.Triggered:Connect(triggerExplosion)Una sola llamada. Cada emisor en el rig se activa según sus propios atributos. El destello es breve, la onda expansiva se despliega, los escombros se dispersan, el humo persiste, la luz pulsa, el tinte de pantalla se dispara, el desenfoque alcanza su pico y se desvanece — todo coordinado por sus tiempos creados, todo activado por una sola llamada de script.
Este es el mismo patrón que genera el botón Emit Code del plugin por defecto. Al seleccionar un rig de VFX de múltiples componentes en Studio y hacer clic en Emit Code se produce un script estructuralmente idéntico al anterior (con las rutas completadas para tu selección específica).
Errores comunes
Sección titulada «Errores comunes»Algunas cosas a tener en cuenta.
Llamar a métodos de emisión antes de :Activate(). Los métodos no generan error — simplemente no animan. Si tus partículas aparecen pero permanecen inmóviles, verifica que :Activate() se haya llamado una vez al inicio del juego. Detalle: Lifecycle.
Establecer atributos después de que :EnableEmit ya está en ejecución. Los atributos se leen en el momento de la llamada a :EnableEmit. Cambiarlos a mitad del ciclo no afectará la emisión en curso. Establécelos y luego llama.
Olvidar la limpieza en efectos clonados. Un efecto clonado con padre en workspace vive para siempre a menos que lo destruyas. Usa task.delay (después de la vida útil de emisión más larga) o un hook de limpieza en una señal de destrucción del padre.
Emitir desde el servidor cuando los clientes deberían manejarlo. Las partículas emitidas en el servidor se replican a todos los clientes, multiplicando el costo de renderizado. Para la mayoría de los VFX, emite en el cliente — cada cliente renderiza solo sus propias partículas, el costo de red es solo el evento disparador. La emisión del lado del servidor es correcta cuando el efecto necesita ser autoritativo (un destello de daño que solo el jugador que recibe el daño debería ver, por ejemplo).
ParticleEmitter nativo dentro de un padre transformado. Cuando :AbsoluteEmit recorre la jerarquía, activa los elementos transformados mediante :EnableEmit, las instancias nativas de ParticleEmitter mediante :Emit(EmitCount) más un toggle opcional de Enabled para EmitDuration, y las instancias de Trail mediante un toggle de Enabled con duración analizada (los Trails transformados incluidos, ya que el runtime los trata igual que los Trails nativos). Valores predeterminados: EmitCount vuelve a 1 si está ausente, EmitDuration a 0 (sin bucle continuo). Establece EmitDuration en el PE si quieres una ejecución continua después de la ráfaga.
¿Qué sigue?
Sección titulada «¿Qué sigue?»Eso es el final del Recorrido. La API del runtime y los cuatro patrones resueltos cierran el lado de scripts del plugin. A partir de aquí, las secciones restantes son material de referencia: la Property Reference para una búsqueda A-Z de cada propiedad, Setup para instalación y autenticación, FAQ & Troubleshooting para problemas comunes, y el Changelog para el historial de versiones.