ImageLabel
Every other type in the Particiliary renders into the 3D world or post-processes the rendered camera image. ImageLabel is different. It emits flat 2D particles into the GUI layer — the same overlay that draws your scoreboard, inventory, health bar, and any other interface element on top of the game world.
Useful for damage numbers floating up over an enemy, score popups, UI sparkles, “+1” notifications, achievement flashes, ammo-pickup animations — any moment in your interface that benefits from particle-style behaviour rather than a single tween.
The architectural model is unlike anything we’ve seen so far. Position is UDim2 (a Roblox UI coordinate, not a 3D CFrame). Motion is polar: a single emission angle plus a spread, in degrees. Velocity is in pixels per second, not studs. Particles parent into a ScreenGui, not into workspace or Lighting. The flipbook system has two sources — child Decal instances or a single spritesheet with grid coordinates.
What it transforms
Section titled “What it transforms”A Roblox ImageLabel instance.
The plugin doesn’t care where the source ImageLabel is parented at authoring time — Studio’s Explorer, a ScreenGui in StarterGui, a BillboardGui somewhere in the workspace. Transform marks the ImageLabel as a Part-Icles emitter and stamps it with the emit-control attributes. At emit time, the duplicates parent to the EmitParent if set, or to a managed ScreenGui the plugin maintains automatically (covered below).
The 2D screen-space model
Section titled “The 2D screen-space model”The first thing to understand is that ImageLabel particles don’t exist in 3D space at all. They live in the camera-relative GUI layer. Their Position is a UDim2 — Roblox’s standard UI coordinate type that combines a scale component (a fraction of the parent’s size, from 0 to 1) and an offset component (a fixed pixel value).
A Position of UDim2.fromScale(0.5, 0.5) (the default) places the particle in the centre of the parent — half the width across, half the height down. A Position of UDim2.fromOffset(100, 200) places it 100 pixels right and 200 pixels down from the parent’s top-left corner. Mixed values combine both: UDim2.new(0.5, 50, 0.5, -20) means “centre, plus 50 pixels right and 20 pixels up.”
Each particle starts at the source’s Position (you set this in the panel, or in Studio’s UI editor) and offsets in pixel space from there as motion accumulates. The Scale component never changes during a particle’s life; only the Offset does.
The polar motion model
Section titled “The polar motion model”Workspace types use cartesian motion: a SpreadAngle cone, a Speed magnitude graph, motion vectors in 3D. ImageLabel uses polar motion: a single launch angle and a magnitude.
Two properties define the launch direction:
EmissionAngle— a single angle in degrees.0°is right (positive X).90°is up (negative Y in GUI coordinates, where Y grows downward).180°is left.270°is down. This is the central direction every particle launches in.SpreadAngle— a single number in degrees giving the random spread around the EmissionAngle. Each particle picks a random angle withinEmissionAngle ± SpreadAngle/2. A SpreadAngle of0produces a tight beam; a SpreadAngle of360produces a fully omnidirectional burst.
The Speed graph is in pixels per second. A Speed of 100 moves a particle 100 pixels along its launch angle each second. A graph that ramps from 200 to 0 is a particle that launches fast and decelerates to a halt over its lifetime — useful for damage-number popups that “rise and slow.”
Acceleration is a Vector2 in pixels-per-second-squared, applied to both axes. A common pattern is (0, 200) for a “gravity-like fall” — every particle’s downward velocity grows by 200 pixels per second per second. Combined with an upward initial velocity, this produces an arc.
Drag works the same as on workspace types: an exponential decay applied to velocity each frame.
Properties at a glance
Section titled “Properties at a glance”The full surface area, grouped by panel section.
Spawning
Section titled “Spawning”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Mode | EmissionMode | enum | Emit | Emit (per-emission clones) or Animate (singleton, looping) |
| Loop | AnimateLoop | boolean | false | Whether Animate mode loops the cycle |
| Enabled | Enabled (attribute) | boolean | false | Master on/off |
| Rate | Rate | number | 10 | Particles per second |
| Lifetime | Lifetime | NumberRange | 1 | Seconds each particle lives |
| Rotation | ImgRotRange | NumberRange | 0 | Random initial rotation in degrees |
| Rotation | ImgRotSpeed | NumberSequence | 0 | Spin graph during life |
| Rotation Mode | ImgRotMode | enum | OverLife | Whether RotSpeed is per-life or per-second |
Appearance
Section titled “Appearance”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Image | Image | string | "" | Roblox asset ID for the texture |
| ImageColor | ImageColor3 | ColorSequence | white | RGB tint over each particle’s life |
| Transparency | ImageTransparency | NumberSequence | 0 | Image opacity over each particle’s life |
| BG Color | BackgroundColor3 | ColorSequence | white | Background colour graph (for non-transparent backgrounds) |
| BG Transparency | BackgroundTransparency | NumberSequence | 1 | Background opacity graph (default fully transparent) |
| ScaleType | ScaleType | enum | Stretch | How the Image fits inside the particle’s Size — Stretch/Slice/Tile/Fit/Crop |
| ResampleMode | ResampleMode | enum | Default | Texture filtering — Default (smooth) or Pixelated (nearest-neighbour) |
Layout
Section titled “Layout”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Position | Position | UDim2 | (0.5, 0, 0.5, 0) | Base spawn position — Scale + Offset per axis |
| Size | ImgSize | UDim2 | (0, 100, 0, 100) | Base particle size — pixels by default |
| SizeScale | SizeScaleX, SizeScaleY | two NumberSequence | 1 | Per-axis size multipliers, animated over life |
| AnchorPoint | AnchorPoint | Vector2 | (0.5, 0.5) | Where on the particle the Position anchors (centre by default) |
| ZIndex | ZIndex | number | 1 | Draw order within the parent ScreenGui |
Motion
Section titled “Motion”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Speed | ImgSpeed | NumberSequence | 0 | Velocity magnitude graph, in pixels per second |
| EmissionAngle | EmissionAngle | number | 90 | Central launch angle in degrees (90° = up) |
| SpreadAngle | ImgSpreadAngle | number | 0 | Random spread around EmissionAngle in degrees |
| Acceleration | ImgAcceleration | Vector2 | (0, 0) | Constant 2D acceleration in pixels/sec² |
| Drag | ImgDrag | number | 0 | Exponential velocity decay |
| Reverse Motion | ImgInvertMotion | boolean | false | Plays trajectory in reverse |
Flipbook
Section titled “Flipbook”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Source | ImgFlipbookSource | enum | Decals | Where frames come from — Decals folder or Spritesheet |
| PlayMode | ImgFlipbookMode | enum | Loop | How frames play — Loop, OneShot, PingPong, Random |
| Grid | GridCols, GridRows | two number | (8, 8) | Spritesheet grid dimensions (only shown if Source = Spritesheet) |
| Framerate | ImgFlipbookFramerate | NumberRange | 10 | Frames per second |
| StartRandom | ImgFlipbookStartRandom | boolean | false | Random start frame per particle |
| Reverse | ImgFlipbookReverse | boolean | false | Plays backwards |
Advanced
Section titled “Advanced”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Anim. Steps | TotalKeyFrames | number | 100 | Pre-sample resolution for the graphs |
| Linger | PartLife | number | 0 | Seconds the particle persists after Lifetime |
| Emit Into | EmitParent | Instance | nil | Where particles parent — overrides the default ScreenGui |
| PreloadTexture | PreloadTexture | boolean | false | Force-loads the Image asset before emit begins |
Per-property prose for the distinctive bits
Section titled “Per-property prose for the distinctive bits”Position
Section titled “Position”A UDim2 for the base spawn position. The panel input is a comma-separated "sx, ox, sy, oy" format — Scale-X, Offset-X, Scale-Y, Offset-Y. So "0.5, 0, 0.5, 0" (the default) is “centre of parent.” "0, 50, 1, -50" is “fifty pixels in from the left, fifty pixels up from the bottom.”
Particles spawn at this Position and accumulate their motion as a delta to the Offset component. The Scale component stays constant — particles don’t reflow with parent size changes mid-life.
A UDim2 for the base size of each particle. Default is (0, 100, 0, 100) — 100 pixels wide and 100 pixels tall, with no scale-relative sizing. To make particles size relative to the parent (so they grow when the screen is bigger), use scale values: (0.1, 0, 0.1, 0) is “10% of the parent in each axis.”
The base Size is multiplied by the SizeScale graphs each frame; the result is the rendered size at any given moment.
SizeScale
Section titled “SizeScale”Two independent NumberSequence graphs (SizeScaleX and SizeScaleY) that multiply the base Size each frame.
A particle that grows wider mid-life uses an oscillating SizeScaleX while keeping SizeScaleY at 1.0. A particle that stretches vertically uses the opposite. A particle that pulses (grows and shrinks together) uses identical graphs on both axes.
This is how 2D particles get their “anime impact” feel — exaggerated horizontal stretch on a hit-flash, vertical squash for a damage-up popup.
EmissionAngle
Section titled “EmissionAngle”A single number in degrees. The central direction every particle launches in.
0° is right (positive X axis in screen space). 90° is up (Y grows downward in GUI coordinates, so “up” is the negative Y direction — the plugin handles the inversion internally). 180° is left. 270° is down. The default is 90° — particles launch upward by default, which is the most common pattern (damage numbers float up, sparkles rise).
For sideways effects like a directional impact splash, use 0° or 180°. For omnidirectional bursts, leave EmissionAngle alone and crank SpreadAngle to 360.
SpreadAngle
Section titled “SpreadAngle”A single number in degrees. Each particle’s actual launch angle is randomly picked from EmissionAngle ± SpreadAngle/2.
0 produces a tight, parallel beam — every particle launches in exactly the EmissionAngle direction. 30 produces a moderate fan. 90 produces a quarter-circle spread. 360 produces a fully omnidirectional burst.
Combined with EmissionAngle, this is the entire direction model. There are no per-axis Position offsets like the workspace types — if you want particles to spawn in different places, set up multiple emitters at different Positions, or script the Position before each Particle:Emit() call.
A NumberSequence graph for velocity magnitude in pixels per second. Multiplied against the unit-vector launch direction each frame.
A Speed of 100 constant moves a particle 100 pixels along its launch direction per second. A graph that decays from 200 to 0 is a “rise and slow” pattern — fast launch, gradual stop. A graph that ramps upward is a “drift and accelerate” — useful for explosion debris animations.
Acceleration
Section titled “Acceleration”A Vector2 in pixels-per-second-squared. Applied to every particle’s velocity each frame, regardless of launch direction.
Since GUI Y grows downward, (0, 300) is “gravity pulling particles toward the bottom of the screen” — useful for damage numbers that float up briefly and then fall. (50, 0) is “a sideways breeze pushing particles to the right.” (0, -100) is “a constant upward force” — particles that gain altitude over time regardless of launch direction.
Exponential decay applied to velocity each frame. Same role as on workspace types. A Drag of 1 cuts velocity to about 37% per second.
For 2D effects, drag is especially useful for particles that should settle rather than just fly — a damage-number popup that drifts up briefly and then comes to a stop in the air uses Drag to slow itself down without a falling-Speed graph.
Rotation
Section titled “Rotation”Three properties together control rotation:
RotRange— aNumberRangefor random initial rotation. Each particle picks a random rotation within this range at spawn.(-30, 30)gives ±30° random orientation;(0, 0)gives every particle the same starting rotation (zero).RotSpeed— aNumberSequencefor rotation speed during life. The semantics depend onRotMode.RotMode— an enum:OverLife(the graph value at agetis the absolute angle in degrees — a graph ramping from0to360spins each particle once over its life, regardless of how long that life is; a constant graph holds a fixed rotation) orSpeed(the graph value at agetis the rotation rate in degrees-per-second; the engine accumulatesvalue × dteach frame, so a constant360spins once per second).
Same model as the workspace types’ rotation, just on the single 2D axis (rotation around the screen normal — particles spin like coins on a table).
Source
Section titled “Source”An enum that picks where the flipbook frames come from. Two options:
Decals— same model as the mesh flipbooks forPartandBeam. The plugin reads childDecalinstances of anImageFlipbooksfolder under the source ImageLabel, sorted numerically by name. Each Decal’sTexturebecomes one frame.Spritesheet— a single Image asset divided into a grid. The plugin computes aRectfor each frame based onGridColsandGridRowsand animates the particle’sImageRectOffsetandImageRectSizeproperties. The default8×8(64-frame square) covers most spritesheet authoring; 8×1 horizontal strips, vertical strips, square 4×4 grids, or any other arrangement work too.
For most authoring, Decals mode is easier (one image per frame, no math). Spritesheet mode is more efficient for animation-heavy effects since one texture loads once.
PlayMode
Section titled “PlayMode”How frames advance. Four options. Same idea as the mesh-flipbook Mode, but with two extra modes that the mesh / beam flipbooks don’t currently support.
Loop (default) — frames cycle continuously at Framerate FPS for the particle’s whole life. Use cases:
- Continuously animating UI sparkles or glints behind a button.
- Looping power-up pulses overlaying a HUD.
- Cycling glow patterns on damage-number popups so the popup itself is always “alive.”
OneShot — frames play once linearly across Lifetime. The first frame appears at age 0, the last frame at age 1, with the last frame holding for any time after the sequence completes. Use cases:
- A “+1” pickup popup whose frames are: appear → swell → settle → fade. The frame progression is the popup’s life cycle.
- Damage numbers whose first frame is a sharp impact effect, then progressively soften.
- UI achievement flashes whose frames trace the bloom-and-fade arc once per emit.
PingPong — frames play forward then backward then forward, oscillating. The animation has a “rest” frame at each end of the cycle and a “peak” frame in the middle. Use cases:
- Breathing or pulsing effects where the texture should swell and contract repeatedly. A 5-frame pingpong (small → medium → large → medium → small → medium → large …) reads as an organic breath.
- UI markers that bob — a hovering arrow whose frames sweep up and back down.
- A loading spinner that doesn’t snap-loop. Where Loop reads as “frame N+1 right after frame N → snap to frame 1,” PingPong reads as a smooth back-and-forth wave with no visual jump.
Random — every 1 / FlipbookFramerate seconds, each particle picks a fresh random frame independently. Unlike Loop’s linear advance through the frame sequence, Random produces a per-particle, jittery-feeling frame stream. Use cases:
- Static-fuzz textures where order doesn’t matter — sparkle dust, screen-grain overlays, broken-signal effects.
- Crackling energy where any of N frames is a valid look at any moment.
- Anything where you want a population to feel desynchronised without authoring per-particle offsets.
Two numbers: GridCols (frames per row) and GridRows (number of rows). Only meaningful when Source = Spritesheet. The plugin computes:
- Frame width =
imageWidth / GridCols - Frame height =
imageHeight / GridRows - Total frames =
GridCols × GridRows - For frame
i:ImageRectOffset = ((i % GridCols) × frameWidth, floor(i / GridCols) × frameHeight)
An 8, 8 grid is a 64-frame square (the default). A 4, 4 grid is a 16-frame square. An 8, 1 grid is an 8-frame horizontal strip. The plugin caches the image’s pixel dimensions on first emit, so the first emission may render the whole image without cropping for a frame or two while the dimension fetch completes.
Emit Into
Section titled “Emit Into”The default parent for emitted particles is a managed ScreenGui the plugin creates lazily under CoreGui. You don’t need to think about this — it appears the first time an ImageLabel emits and is destroyed when you deactivate the plugin.
Override Emit Into to point at your own ScreenGui (or any UI container) when you want particles inside a specific frame, above specific other UI elements, or under your game’s Z-index management. A common pattern is to put a ScreenGui named Effects inside PlayerGui and point ImageLabel emitters at it, so the effects participate in your game’s UI render order.
PreloadTexture
Section titled “PreloadTexture”A boolean. Same role as on Beam/Trail: forces the texture asset to load before emit begins, preventing the first few particles from rendering with no image while the asset streams in.
For tight cinematic timing, turn it on. For most uses, leave it off.
Worth knowing
Section titled “Worth knowing”A few ImageLabel-specific quirks.
3D-to-screen tracking is your responsibility. ImageLabel particles don’t automatically follow 3D objects. If you want a damage number to appear above an enemy who’s somewhere in the 3D world, you have to compute the screen-space coordinate of the enemy yourself (typically with Camera:WorldToScreenPoint) and write it to the ImageLabel emitter’s Position attribute before triggering the emission. There’s no built-in “track this 3D point” toggle.
ImageColor3 multiplies, doesn’t replace. A red ImageColor3 doesn’t repaint the texture red — it multiplies the texture’s RGB by the colour’s RGB. If your texture is white, the result is red. If your texture is blue, the result is black (red × blue = no overlap). For solid-tint particles, start with a white-pixel texture; for textured particles, design the texture’s base colour with the multiplication in mind.
The default Position is centre-of-parent. (0.5, 0, 0.5, 0) puts the particle at the parent ScreenGui’s centre. For damage numbers over a 3D enemy, this is wrong — you’ll want to override Position before each emit. For UI flourishes that should always trigger from the same screen position (a heart icon flashing in the top-left), the default works fine.
Decals folder is hidden during emit. When the plugin clones the source ImageLabel for emission, it strips the ImageFlipbooks folder from the clone (the clone doesn’t need to carry around the frame Decals — the engine reads them from the source’s folder once, caches them, and uses the cached list per particle).
Animate mode is singleton. Same as the screen-space types — only one Animate-mode duplicate alive at a time, re-emits while alive are silently dropped. Works the same way for ImageLabel as for Blur/Bloom/ColorCorrection.
Performance tolerates high rates. UI rendering doesn’t go through the 3D pipeline (no skinning, no shaders, no shadow casting). High Rate values like 100 or 200 particles per second are viable on mid-range hardware. The cost is mostly in graph evaluation and per-particle property updates, not in the rendering itself.
The default Image = "". A new ImageLabel emitter with the default empty Image renders… nothing. You have to set an Image asset before particles will visibly appear. The panel’s Image field accepts rbxassetid://... URIs or the asset id directly.
End of the Particiliary
Section titled “End of the Particiliary”That’s all eleven types. Workspace, screen-space, UI — eleven different ways to turn a Roblox instance into a custom particle emitter:
- Workspace 3D:
Part,Attachment,Beam,Trail,PointLight,Model. - Screen-space post-process:
Blur,Bloom,ColorCorrection,Atmosphere. - UI 2D:
ImageLabel.
You’ve now seen the architectural surface of every emitter the plugin supports. The next chapter shifts back from the type catalogue to broader plugin features, starting with Textures and Flipbooks — how textures and flipbooks land on a transformed emitter, and how the Dissect tool slices any public Roblox spritesheet into a flipbook at full resolution.