rParticle: The Light Weight, Open Source, GUI Particle System

Hi, this is my first time making an Open Source project, so please feel free to give me lots of constructive criticism. :grin: :grin:

Recently updated to version 1.2 https://github.com/JoelDesante/rParticle/releases/tag/1.2 | 1/15/2021


The Light Weight, Open Source, GUI Particle System.
Source Code | Download

What is rParticle?

rParticle is a small module (around 80 lines of code) which was made with the sole intention of allowing developers to quickly and easily make 2D GUI particle systems.

rParticle is set up in such a way that basically all of the particle “logic” is handled by the creator while the tracking, updating, data, and “rendering” of the particles are handled by the module.

How do I use rParticle?

It is my opinion that rParticle is exceedingly easy to use. I was able to create the following effect in only ~28 lines of code:

Here is how this 3D Gui particle effect is done:

Step 1: Install rParticle

Just download the module and put it somewhere that you can easily access it. I tend to put mine in ReplicatedStorage.

Step 2: Create your particle

rParticle was created to give as much control over the particle as possible to the developer. This means that the particle can be (for the most part) any GUI Object (ie Frame, Button, TextLabel, ViewportFrame, etc…)

In this example, I created a ViewportFrame called ParticleVP.
Inside of this ViewportFrame I placed a model of my character and a LocalScript.

The contents of the local script are:

local RunService = game:GetService("RunService")
local Model = script.Parent.Yooogle
local part = Model.HumanoidRootPart
local Viewport = script.Parent

local Camera = Instance.new("Camera")
Camera.Parent = Viewport

Viewport.CurrentCamera = Camera

	Camera.CFrame = CFrame.new(part.CFrame.p + Vector3.new(-5,3,5), part.Position)
	Model:SetPrimaryPartCFrame(part.CFrame * CFrame.Angles(0, math.rad(delta*100), 0))

Finally, I stored the Particle in ReplicatedStorage

Step 3: Create the ParticleEmitter

To emit the particles, you will need two components.

  1. A particle to emit.
  2. An element to “hook” into.

In this example, I used a Frame, but you could use pretty much any GUI object.

The code I wrote to emit the particles is as follows:

local ParticalEmitter = require(game.ReplicatedStorage.ParticleEmitter).new(script.Parent, game.ReplicatedStorage:WaitForChild("ParticleVP"));
ParticalEmitter.rate = 10;

ParticalEmitter.onSpawn = function(particle)
	particle.velocity = Vector2.new(math.random(-700, 700), 500);
	particle.maxAge = 10;

ParticalEmitter.onUpdate = function(particle, deltaTime)
	particle.velocity = particle.velocity - Vector2.new(0, 10);
	particle.position = particle.position - (particle.velocity/3 * deltaTime);

On the first line, I am including the ParticleEmitter module and creating a new ParticleEmiter using .new(). The first argument I pass in is the “hook” and the second is the particle.

As you can see, there are various properties that you can set, many of which are listed on the GitHub README.

In this example, I am setting the rate of the emitter to 10 particles per second.

Then, below, I modify the callbacks onSpawn() and onUpdate() to handle the logic of the particles.


I hope this module helps some people out there. Let me know if there are any questions, as I am aware that my documentation might leave some things to be desired. I am still new to the Open Source world, so I will be working to get better at writing documentation.

Thank you for reading!


Feel free to respond to this thread with any questions or requests for help.

1 Like

This looks like it would come in real handy for UI designing.

Keep up the great work!

1 Like

Thank you very much! Im glad you like it.

Can you tell me step 3 again please?? I can’t understand it properly…

1 Like

Let me clean it up a bit. It might help.

local Replicated = game:GetService("ReplicatedStorage")

local ParticleEmitter = require(Replicated.ParticleEmitter)
local ParticleVP = Replicated:WaitForChild("ParticleVP")
local Particle = ParticleEmitter.new(script.Parent, ParticleVP)

Particle.rate = 10

Particle.onSpawn = function(particle)
	particle.velocity = Vector2.new(math.random(-700, 700), 500)
	particle.maxAge = 10

Particle.onUpdate = function(particle, deltaTime)
	particle.velocity = particle.velocity - Vector2.new(0, 10)
	particle.position = particle.position - (particle.velocity/3 * deltaTime)

ParticleVP is the name of the Instance that is created in step 2, and stored in ReplicatedStorage.

1 Like

thanks!! its rlly helpfull… Thanks so much…


Hmm, this is quite interesting, thank you for script! You get a like from me! I’ll use it in my game later

1 Like

Hey there! Thank you so much for making this module! It is probably one of the most useful I have seen. I do have one question. Is there any way to destroy the ParticleEmmitter? I have tried making the maxAge a negative number, but that just makes it flash.

Edit: I have found a destroy function inside the module, but it does not seem to work.


Sorry for bumping this topic, at least it wasn’t a year old.

1 Like

How would you go about making this work with a billboard ui to use as a damage indicator? I’m having issues with getting it to work.

1 Like

Sorry for the late response!

The destroy function just destroys a Particle not the emitter. MaxAge also applies to the Particles and not the emitter.

I’ll look into adding this in to a future update.

1 Like

Hi, sorry for the delayed response. Right now the ParticleEmitter code uses RenderStepped which is only able to be accessed from the client. Assuming your billboard is on the server side, the code, as it stands will fail.

I can simply resolve this by using something like Stepped instead. I’ll look into this and resolve this in a future update (possibly out tonight if I have time).

Particles with Billboard UI

Just a minor update. I’ve made some changes to the code and I’ve fixed a bad bug that I discovered.

Version 1.2

Adds the ability to destroy particle emitters

Changes the update loop to RunService#HeartBeat() so that the script may be used on the server side too.