Emitter2D - Convert any ParticleEmitter to 2D with the click of a button!

What is Emitter2D?

Emitter2D is a plugin and module that enables you to create diverse UI particles without coding. To create emitters, you insert 2D emitter objects into UIs the same way you insert regular 3D emitters into parts! The properties of these emitters are stored as attributes, so they can be edited from the properties panel just like regular 3D emitters.

What is it capable of?

Emitter2D is designed to replicate all of the functionality of regular 3D emitters, including things like Flipbooks, TimeScale, Orientation based on velocity and more. In fact, the plugin comes with a tool to convert regular 3D emitters into 2D emitters!

2025-03-0815-27-01-ezgif.com-video-to-gif-converter (2)

Emitter2D also includes some features lacking from regular emitters, as well as several 2D-specific features. Check out the Property Guide section at the bottom of the post for details.


Installing Emitter2D

Step 1 - Install the plugin

Click the link and install the plugin: Emitter2D - Creator Store

Step 2 - Find the toolbar

In studio, you should see a new toolbar in your plugins section:

Step 3 - Install the Client

Click the Install Client button. This ensures that the particles will work in-game. Every time you update the plugin, you should click this button again to update the in-game code.

Note: If the particles still don’t work in-game after clicking Install Client you may need to enable the script injection permission for the plugin. To do this navigate to Plugins (Top left) → Manage Plugins and find Emitter2D in the plugin list, then enable the script injection permission. Make sure to press Install Client again after this is done to ensure the client has been installed.


Making your first emitter

Step 1

First, select an existing GUI that you want to add an emitter to:

Step 2

Next, click the Create Emitter button on the plugin toolbar. This should create a basic 2D emitter object under the selected GUI:

2025-03-1015-32-53-ezgif.com-video-to-gif-converter

Step 3

To change the behavior of the emitter, make sure the emitter object is selected and navigate to the properties panel, you should see a long list of attributes:

Many of Emitter2D’s properties behave the same as their regular emitter counterparts. For those that don’t, check out the Properties Guide section at the bottom of this post.


Creating 2D emitters from 3D emitters

Step 1

First, select the regular 3D emitter(s) that you want to emulate:

Step 2

Next, click the Convert Emitter button on the plugin toolbar. A 2D emitter object should be created under each of the regular emitters you had selected:

Step 3

Next, drag and drop these 2D emitter objects into the GUI object you want them to originate from:

Step 3b

Alternatively, you could cut and paste them into the desired GUI object, or navigate to the properties panel, click the Parent property, and then click the desired GUI object.


Coding

Currently the coding API is very limited, but there are three BindableEvents under each emitter that allow limited control similar to regular emitters. There are plans to add a much more robust coding API detailed in the Planned Features section.

Emitter.Emit:Fire(particleCount : number)

  • Immediately spawns the requested number of particles.
  • Works even if Emitter.Enabled = false.

Emitter.TimeStep:Fire(deltaTime : number)

  • Progresses the simulation for this emitter forward by the requested amount of time.
  • Works even if Emitter.Paused = true.

Emitter.SetSeeds:Fire(seeds: { [string]: number })

  • Sets the seeds the emitter uses when determining the properties of particles when they spawn, causing the emitter to spawn particles in the same pattern every time. This is especially useful for layering particles on top of each other. Seed is set separately for each property so you can keep some properties random while keeping the desired ones in sync.

  • Seed options: Position, Scale, FlipbookFramerate, SpreadAngle, Color, Speed, EmissionRate, Size, Rotation, Transparency, FlipbookStartRandom, Squash, RotationSpeed, Depth, DepthTransparency, LifeTime

Emitter.Clear:Fire()

  • Clears all particles spawned by this emitter.


Planned Features

More robust Coding API

  • Currently the ability to change particle behavior with code is very limited. I plan to refactor the module to enable far greater customizability with the following additions:
    • The option to spawn particles at specific positions, velocities, rotations, etc.
    • The option to set particle update callbacks to add complex custom behavior to particles.
    • Possibly the option to create custom properties.

SurfaceGui support

  • You’ll be able to insert particle emitters into SurfaceGuis, and they will scale relative to the SurfaceGui resolution rather than your screen.

Leave a suggestion

  • Found a bug or have a feature you want to suggest? Leave a reply and I’ll consider adding it!


Known Limitations

By nature of how Emitter2D particles are created, they have several limitations. I have listed the major ones below.

Known Limitations

Lower performance than regular 3D emitters

Emitter2D particles run considerably slower than regular 3D emitters. This is because, like all other 2D emitters, particles are created using ImageLabel GUI objects which aren’t optimized for this type of functionality. This means:

  • You will not be able to use as many 2D emitters at a time as 3D emitters. Be careful when applying them to things there can be high quantities of, such as items in inventories.
  • You will need to lower the Rate property for many 2D emitters that were converted from regular 3D emitters.
  • You may need to dynamically lower the Rate of emitters for mobile users- or disable them entirely.

LightEmission, Brightness, and Black Backgrounds

Roblox GUIs do not support light emission or brightness.

Because of the lack of support for LightEmission, which is what enables black backgrounds to be rendered transparent, some particle textures that work with regular emitters will not work with Emitter2D. Below is an example of what this looks like:

2025-03-0816-36-43-ezgif.com-crop

I could theoretically implement Brightness and LightEmission using EditableImages, but the current Roblox limitations where only assets the game creator owns can be edited as well as memory limits caused by the inability to compress image data after editing make the benefits of doing so quite limited. If people request this enough I may implement it anyway, but until then you can fix this yourself using image editing software to remove the background manually.

High network usage and lag in Team Create

It’s important to keep in mind that other users that have the studio preview enabled will increase network and CPU usage for you and other clients in Studio Edit mode. This is because Roblox automatically replicates any particle GUIs in StarterGui to other editing clients. If you have the plugin, particles created by other clients are hidden for you, but they still exist and use processing power when they are updated. If you notice higher network usage or lag than normal, try asking other users in the team create to disable their Emitter2D previews.

Plugin non-users will see other users particle previews

Because Emitter2D plugin is required to hide particles from other user’s Emitter2D previews, users without the Emitter2D plugin will be able to see particles from other user’s previews.


Properties Guide

Below is an expansive list of emitter properties and their behaviors. The properties Size, Scale, EmissionDirection, and Squash are particularly important to review as they behave quite different than regular emitters.

Properties Guide

General

  • Enabled : A true/false value that toggles the emitter on or off. When disabled, the emitter will stop spawning new particles, but existing particles will continue their lifecycle.
  • TimeScale : A number that acts as a multiplier for the entire emitter’s speed. A value of 1 is normal speed, 0.5 is half speed, and 2 is double speed. This affects particle lifetime, movement speed, and emission rate.
  • Paused : A true/false value that completely freezes the emitter’s simulation. No new particles will spawn, and existing particles will be frozen in place until this is set to false.
  • ZIndex : Determines the rendering order of the particles relative to other UI elements. A higher number will make the particles appear on top of elements with a lower number.
  • IgnoreGraphicsLevel : A true/false value. If true, the emitter will ignore the player’s graphics quality settings and always emit particles at the full rate. If false, the emission rate will be reduced for players on lower graphics settings to improve performance. Currently, rate is reduced by 15% per graphics level below 10, resulting in about 1/4th the spawn rate for graphics level 1 versus 10.

Emission

  • EmissionRate : A NumberRange that controls how many particles are spawned per second. Unlike Roblox emitters which use a single number, this allows for a variable rate. For example, a range of 10 to 50 will cause the emitter to randomly spawn between 10 and 50 particles each second, creating a “bursty” or inconsistent emission pattern.
  • EmissionRateScaleByArea : A true/false value that, when enabled, automatically scales the EmissionRate to maintain a consistent particle density as the emitter’s UI element changes size.
    • If EmissionShapeStyle is “Volume,” the rate scales with the UI’s area.
    • If EmissionShapeStyle is “Surface,” the rate scales with the UI’s perimeter length.
  • EmissionShape : Determines the shape of the area from which particles are spawned.
    • Rectangle : Particles spawn from anywhere within the bounds of the parent UI element.
    • Oval : Particles spawn from within an oval shape that fits inside the parent UI element.
    • Point : All particles spawn from the exact center of the parent UI element.
  • EmissionShapeStyle : Defines where on the EmissionShape particles will appear.
    • Volume : Particles can spawn anywhere inside the shape.
    • Surface : Particles will only spawn along the edge or outline of the shape.
  • EmissionDirection : Sets the base angle, in degrees, that particles will travel when they are first created. An angle of 0 points up, 90 points right, 180 points down, and 270 points left.
  • EmissionDirectionMode : Modifies the final emission direction based on the particle’s spawn position.
    • FromUp : All particles travel in the direction set by EmissionDirection , regardless of where they spawn.
    • FromCenter : Particles will fly away from the center of the EmissionShape . The final direction is a combination of the EmissionDirection and the angle from the shape’s center to the particle’s spawn point.
    • FromSurface : The particle’s initial direction is determined by the angle of the surface at its spawn point, combined with the base EmissionDirection . This is intended for the Oval and Rectangle shapes, causing particles to fly outwards from the shape’s edge.
  • SpreadAngle : A number in degrees that adds randomness to the emission direction. A value of 45 means a particle’s final direction can be up to 22.5 degrees to the left or right of the EmissionDirection. A value of 360 will cause particles to fly out in all directions.

Appearance

  • Texture : The image URL (like rbxassetid://... ) used for each particle. If you insert just the asset number, rbxassetid:// will automatically be appended to the resulting value.
  • Color : A ColorSequence that controls the color of a particle over its lifetime.
  • Transparency : A NumberSequence that controls the visibility of a particle over its lifetime. A value of 0 is fully visible, and 1 is fully invisible.
  • Size : A NumberRange that determines the base size of the particles. This is different from Roblox emitters. Instead of using a NumberSequence, this sets the initial size, which is then changed over time by the Scale property. See SizeConstraint for more info about how size is calculated.
  • Scale : A NumberSequence that multiplies the particle’s base Size over its lifetime. This allows the particle to grow or shrink over time. A value of 1 is its normal size, 0.5 is half, and 2 is double.
  • Squash : A NumberSequence that stretches or squashes the particle’s shape over its lifetime. This behavior is similar to Roblox’s Squash, but the value is mapped from 0 to 1 instead of -3 to 3.
    • A value of 0.5 results in no squashing.
    • Values from 0 to 0.5 will squash the particle horizontally, making it taller and thinner.
    • Values from 0.5 to 1 will squash the particle vertically, making it shorter and wider.
  • MasterScale : A single number that uniformly multiplies the size and speed of all particles. Useful for scaling the entire effect up or down without changing other properties.
  • SizeConstraint : Determines how the particle’s size is affected by the container dimensions.
    • Offset : The size is always measured in pixels and is not affected by container size.
    • RelativeYY : The size is scaled relative to the container’s height.
    • RelativeXX : The size is scaled relative to the container’s width.
    • RelativeMin : The size is scaled relative to whichever container dimension (width or height) is smaller.
    • RelativeMax : The size is scaled relative to whichever container dimension (width or height) is larger.
  • UseScreenSize : A true/false value used with SizeConstraint . If true, the particle scales relative to the entire screen. If false, it scales relative to the size of the parent UI element.
  • UseJitterFix : A true/false value that, when enabled, rounds the size of a particle in pixels to the nearest even number to help reduce visual jittering of particles when they change size.

Movement & Rotation

  • Speed : A NumberRange that sets the initial velocity of a particle in pixels per second. A random value between the minimum and maximum is chosen for each new particle.
  • Acceleration : A Vector2 value that applies a constant force to the particles, changing their velocity over time. This can be used to simulate effects like gravity (e.g., a positive Y value like (0, 1000) ) or wind.
  • Drag : A number that simulates air resistance, causing particles to slow down over time. A value of 0 means no drag. Higher values will cause particles to slow down more quickly, while negative values will cause them to speed up.
  • Orientation : Controls how the particle’s rotation is determined.
    • Normal : The particle’s rotation is controlled only by the Rotation and RotationSpeed properties.
    • VelocityParallel : The particle will automatically rotate to face the direction it is moving.
    • VelocityPerpendicular : The particle will automatically rotate to be perpendicular (at a 90-degree angle) to its direction of movement.
  • Rotation : A NumberRange that sets the initial rotation of a particle in degrees.
  • RotationSpeed : A NumberRange that determines how fast a particle rotates over its lifetime, in degrees per second. A positive value is clockwise, and a negative value is counter-clockwise.
  • LockedToGui : A true/false value. If true, the particles will move and rotate with the parent UI element as if they are attached to it. If false, particles will retain their position relative to the screen when the parent UI element moves or rotates.
  • VelocityInheritance : A number from 0 to 1 that controls how much of the parent UI element’s movement speed is transferred to newly spawned particles. This only has an effect if LockedToGui is false.

Lifetime & Depth

  • LifeTime : A NumberRange that sets how long a particle will exist, in seconds. A random value between the minimum and maximum is chosen for each new particle.
  • Depth : A NumberRange that simulates a 3D depth effect. Particles with a higher depth value will appear smaller and move slower, as if they are farther away. Negative depth will make particles larger and faster, as if they are closer to the viewer.
  • DepthTransparency : A NumberSequence that controls how a particle’s transparency is affected by its Depth . This can be used to make particles that are “farther away” (or closer) appear more faded.

Flipbook

(Flipbooks are short animations using a single image. The image is a grid of frames.)

  • FlipbookLayout : The grid size of your flipbook texture.
    • None : The texture is not a flipbook. Use this to disable flipbooks entirely.
    • Grid2x2 : A 2x2 grid (4 frames total).
    • Grid4x4 : A 4x4 grid (16 frames total).
    • Grid8x8 : A 8x8 grid (64 frames total).
  • FlipbookMode : Determines how the animation plays.
    • OneShot : Plays through the animation once from start to finish. This mode ignores FlipbookFramerate and instead paces the animation to end on the last frame exactly when the particle’s lifetime expires.
    • Loop : Plays the animation and repeats from the beginning once it finishes.
    • PingPong : Plays the animation to the end, then plays it backward to the beginning, and repeats.
    • Random : Jumps to a random frame at a rate determined by FlipbookFramerate .
  • FlipbookFramerate : A NumberRange that sets the animation speed in frames per second.
  • FlipbookStartRandom : A true/false value. If true, each particle will start on a random frame of the animation. If false, they all start on the first frame.
  • FlipbookResolution : The pixel dimensions (width and height) of your square flipbook texture. For example, 1024 for a 1024x1024 image. Like regular emitters, the resolution must be a power of 2 between 8 and 1024.
  • ResampleMode : Determines how the image is rendered when scaled up or down, affecting its sharpness or smoothness. This uses Roblox’s standard ResamplerMode enum.

Misc

  • ClassName : A read-only attribute identifying the object as an Emitter2D . It cannot be changed.
  • Version : The internal version number of the emitter’s configuration. This is managed automatically and cannot be changed manually.
  • IgnoreClipsDescendants : If true, particles will continue to spawn even if the parent UI element moves outside of an ancestor’s clipping bounds (e.g., a ScrollingFrame ). If false, particles will stop spawning if the emitter is not visible on screen. I recommend keeping this setting disabled.
101 Likes

I’m most likely going to use this. I do have one request, mainly for consistency. Could the function Fire() be renamed to Emit(), similar to the ParticleEmitter? Also, what properties of a ParticleEmitter are not present in your module (like EmissionDirection)?

He uses :Fire() because he somehow uses BindableEvents.

Hey, after using this for my game there’s one part of the module script that broken/written incorrectly. On line 743, the module script asks if self.Active then. I kept getting the warning about needing the emitter to be parented to a GUI object, which it was. So I looked through and saw that the result of the active checks are then stored into self.ValidAncestry and switched out self.Active with self.ValidAncestry in every mention of Active and it works. I can’t tell if this is just a workaround or if this was an oversight but you should probably know about this.

2 Likes

Good find, that code was written before I implemented the ancestry checks and I forgot to update it. I’ll push an update to fix it by tomorrow, can’t update immediately as I’m in the middle of adding a couple features.

Edit: This is now fixed

1 Like

THIS IS WHAT IVE BEEN WAITING FOR!!

i saw this plugin MONTHS ago in the toolbox and immediately fell in love with it. so far ive used it for multiple things such as HUD indicators, particles in a skill tree ui, and achievements.
this is a really good plugin for ui creators or even vfx artists who want to spice up their visuals, and i heavily recommend it. it may take some time to get used to when transferring from 3d particles, but it is definitely worth the effort.
thank you for making such a wonderful resource!

below are some of the achievement unlocking effects that i made with emitter2d. again, super amazing plugin!

55 Likes

if there’s one suggestion i would give, it would be to add a seed system for the randomized rotation/velocity properties. due to imagelabels not supporting brightness or lightemission properties, users have to manually simulate glow effects with a second particle. however, they wont be aligned with the primary particle, which might look a bit strange.
if this is possible to be added, it would be greatly appreciated!

3 Likes

That’s an interesting suggestion. I’m pretty busy right now but I’ll try to add it next weekend; I’ve added it to the planned features section. Nice effects btw!

4 Likes

Wonderful graphic addition! I have nothing more to suggest as far as this forum goes. Keep up the good work!

2 Likes

Could you please give each individual particle ImageLabel the same ZIndex as the parent ParticleFrame? Currently, all particles have a default ZIndex of 1 regardless of the attribute value, making the module not support Guis with the “Global” ZIndexBehavior.

I end up having to write a workaround fix for this, but making it officially supported would be greatly appreciated.

Sure, I’ll release this in the next patch. I’ll also disable depth-based ZIndex ordering when a ZIndexBehavior = Global ancestor is detected.

1 Like

Both of these requests are now implemented! As for the seeds, you can set a separate seed for each and every rng-based property separately, read the description in the coding section for details.

2 Likes

you are COOKING with these effects dude. these look amazing

1 Like

This is probably one of the best plugins out right now. Can’t wait to fully learn it!

Insane plugin, amazing work, quick suggestion, when converting it doesnt make an attribute called EmitCount, and EmitDelay, which alot of VFX makers use, if it does have this feature let me know cuz i need it, thanks

I’ve been trying to get this to work however while the preview is working fine, it is not running in play-testing.
I tried firing the BindableEvents on the client however it cannot find them.
It’s Enabled, does it have to be on the server or something? It’s just not doing anything.

Make sure to click the Install Client button on the plugin toolbar, on first install as well as every time you update the plugin. It inserts the scripts necessary for it to run in-game and be shown to players. You may have to give the plugin permission to insert scripts.

1 Like

That was it, i thought I had installed it but evidently not :slight_smile: thanks

1 Like

I won’t add these attributes to the emitter officially since they would only be used by third party code, but I’ll compromise and make it so they don’t get removed if you add them manually.

1 Like

Would it possible to add LightEmission and Brightness? it would be really helpful!