Preview
Plays emitters in Roblox Studio without starting a playtest, so you can change a property and see the result a few seconds later. It's a module inside Spray that nothing else requires, so it never runs in your game.
Select a ParticleEmitter in the Explorer, or a Frame or ScreenGui that has some inside, then paste this into Studio's command bar and press Enter:
require(game.ReplicatedStorage.Packages.Spray.Preview).Play()
The selected emitters play in bursts, over and over, right in the edit viewport. This works for UI in StarterGui, because Studio draws StarterGui on top of the viewport while you edit. Preview reads the emitters when it starts, so after changing a property, run Preview.Play again to see it.
To stop:
require(game.ReplicatedStorage.Packages.Spray.Preview).Stop()
Stop before you save
To make the emitters visible, Preview turns on any hidden UI above them (Visible on
GuiObjects, Enabled on ScreenGuis), and Preview.Stop turns it back off. If you save
the place before stopping, that UI is saved turned on.
Every function returns a one-line message saying what it did, such as how many emitters
are playing. Wrap the call in print() to see it in the Output window.
The Spray Studio plugin has a Preview button that does the same job with a playback window, and picks up property changes on its own.
Types
Options
interface Options {Count: number?--
Particles per burst. The default is 30. An emitter with a BurstCount number attribute uses that instead.
Interval: number?--
Seconds between bursts. The default is the longest Lifetime Max among the emitters plus 0.45, so each burst ends before the next one starts.
Seed: number?--
Uses this seed for every burst, so each loop looks the same. Handy for comparing an effect before and after a change.
Show: boolean?--
Turns on hidden UI above the emitters so you can see them. The default is true.
}Settings for Preview.Play. Every field is optional, and so is the table itself.
local Preview = require(game.ReplicatedStorage.Packages.Spray.Preview)
print(Preview.Play(nil, { Count = 50, Seed = 3 }))
Functions
Stop
Preview.Stop() → string--
A message that says how many leftover Frames were deleted.
Stops the preview and puts the place back the way it was. It destroys every Spray the preview made, turns hidden UI back off, and deletes any leftover particle Frames it finds in StarterGui.
The leftovers come from requiring the module again after editing it while a preview was
running. The new copy doesn't know about the old preview, so Stop finds the old Frames
by name instead (Spray names them Spray_ plus the emitter's name) and deletes them.
CAUTION
That search deletes every Frame whose name starts with Spray_ in StarterGui (and in your
player, during a playtest), including your own. Don't give your UI names that start that
way.
Play
Preview.Play() → string--
A message saying how many emitters are playing, or why nothing is.
Starts looping the emitters in Target, or in whatever is selected in the Explorer if you
don't pass anything.
Target can be a ParticleEmitter or anything that contains some: a Frame, a ScreenGui,
even all of StarterGui. Every emitter inside it plays, all of them bursting at the same
time. When it uses the selection, only the first selected object counts.
local Preview = require(game.ReplicatedStorage.Packages.Spray.Preview)
Preview.Play(game.StarterGui.Shop.BuyButton) -- every emitter in the button
Preview.Play(nil, { Count = 80 }) -- the selection, 80 particles per burst
Emitters that aren't inside a GuiObject are skipped, and the returned message lists them. If a preview is already running, it's stopped first.
Scrub
Preview.Scrub(Time: number--
Seconds into the burst.
) → string--
A message saying the moment and how many emitters were frozen.
Freezes every previewed emitter at Time seconds into a burst and stops the loop. The
picture holds still, which helps when you're looking at a Size or Transparency curve and
want to see one exact moment of it.
local Preview = require(game.ReplicatedStorage.Packages.Spray.Preview)
Preview.Play(nil, { Seed = 1 })
Preview.Scrub(0.15) -- the burst 0.15 seconds in
Each call starts a fresh burst, so without the Seed option you get different particles
every time you scrub. After editing a property, call Preview.Play and then Scrub
again to see the change.
Needs a preview started with Preview.Play first.
Step
Preview.Step(Delta: number--
Seconds to move. Negative values go back.
) → string--
A message saying how far it moved.
Moves the frozen moment by Delta seconds. Negative values go back. Use it after
Preview.Scrub to go through a burst a little at a time, for example to find the exact
moment a curve starts looking wrong.
Preview.Scrub(0)
Preview.Step(0.02) -- run this line a few times
Call Preview.Scrub first. Without it, Step stops new bursts from firing, but the burst
already on screen keeps playing.
Resume
Preview.Resume() → string--
A message saying the preview is looping again.
Unfreezes the preview after Preview.Scrub or Preview.Step. The frozen burst plays out from where it stopped, and new bursts start again after the usual interval.