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.1 Release rParticle 1.2.1 · joeldesante/rParticle · GitHub | 5/6/2022

rParticle

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

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

RunService.RenderStepped:Connect(function(delta)
	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))
end)

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 ParticleEmitter = require(game.ReplicatedStorage.ParticleEmitter).new(script.Parent, game.ReplicatedStorage:WaitForChild("ParticleVP"));
ParticleEmitter.rate = 10;

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

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

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.

Conclusion

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!

268 Likes

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

3 Likes

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

Keep up the great work!

4 Likes

Thank you very much! Im glad you like it.

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
end

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

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

6 Likes

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.

P.S.

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).
dba48839dcc6d93eaec0ade7ffce3cb1

Particles with Billboard UI

3 Likes

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
ParticleEmitter#Destroy()

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

3 Likes

Just bookmarked the post. This will be very handy for UI Designing.

1 Like

Thank you. I’m glad you liked my work!

1 Like

How will I make a particle that does this when I click on a button?

1 Like

Looks like the spray animation is just a bunch of circles flying off into random directions and then dissipating.

You just need to create a circle image. Use an image UI element to represent the particle. Then when the particle is created set the direction and speed to something random within a short range. Then reduce the opacity of the particle as it reaches the end of its life cycle.

2 Likes

Thank you for this. I used this for my Daily Login Reward confetti effect to make it more exciting! Saved me some time… :smiley:

1 Like

How would i make it appear at the players mouse position and how would i make it get destroyed after a moment?

will there be flipbooks lol

Im not sure what you are asking? Can you elaborate?

Where do I get rbxm file for the current latest release?
On Github there’s no rbxm file for 1.2.1 but older versions has it