If you’re planning on making an integrated server particle emitter, The best way to do it would be to simply fire a RemoteEvent to all clients that then emit the particles with the same properties that were sent in from the RemoteEvent
I will be probably releasing Version 3 Today (UTC+1).
Spoiler: There will be better collision script. Particles will not be stuck in Players anymore.
That will be the final version.
Don’t worry, you will still be able to give me ideas that i could implement. And I will continue to fix bugs if you find any.
Update 3
-Changed Collision Code to be more accurate. Now particles don’t get stuck in players.
-Added new Function AddForce. It can be used to add Forces like Repel or Turbulence. Tutorial is in Functions Section.
-Added new Property called BeforePhysics. It runs passed function before physics are calculated.
OK GUYS. I CAME UP WITH A CRAZY IDEA.
So. Having particles that can collide with the world is a good idea.
BUT WHAT IF PARTICLES COULD COLLIDE WITH EACHOTHER!!!??!?!??!?!?!
I present to You…
Particles that can collide:
They are still in testing. They will be released in next update
Performance
For the best performance, Collisions use Spatial Partitioning. In this video it uses 4 Iterations and i still got 60 Fps.
You:
Also you:
Great idea!
Excited for the next update!
Well. That was supposed to be the final version. But when i found out that lag isn’t created by calculations but by updating Visual Particles Positions, i tried adding Collisions Between Particles. But updates after the next update will be smaller.
This looks very cool! Makes me really want to use it, and I probably will.
Update 3.1
I didn’t wanted for you guys to wait for something that should be already in this module. So i am posting this update right now. Remember it might be Glitchy. If you find any glitch please report it to me.
-New Three Experimental Properties: SelfCollisions, SelfSize, Iterations. It makes it possible to simulate particles that collide with eachother.
-New Property SimulateTurbulence. It tries to fake Objects affecting wind which affects Particles.
I also updated the place so that you can test these right now.
Is someone gonna Criticize my Module? No one said that it lacks a feature or performance is bad on their device or it is glitchy. Is my Module Perfect?
Update 3.2
I saw that the code for calculating Collisions between particles wasn’t good for some use cases, so here is the update that sohuld fix it.
-There are three new Properties added: SelfCollType, FluidForce, Mass.
SelfCollType changes the collisions type. There are currently 3 types: Default (The one that was used in Version 3.1), Realistic (A realistic type. Can be used to simulate Ball Pit), Fluid (A fluid type. It makes it possible to simulate fluids.)
FluidForce changes the force of Fluid when SelfCollType is set to ‘Fluid’.
Mass changes the mass of particles when SelfCollType is set to ‘Realistic’.
-There is also added a better Collision code.
Can someone please try the Demo Place and tell at which quality they have Stable FPS? It might help me Optimizing the code. And if you can i would like to know on what device you are playing and how many cores your Cpu has. You can check FPS in game by Pressing Shift + F5. Thanks!
I got 60FPS on:
Sparks and Water Demo - NASA
Snow Demo - Extreme
Rain - Extreme
Hi, one feature I think that could help is :EmitAtPosition
Sometimes I want to emit particles but not at a specific part. One example of this is an explosion, I’d like to have particles for an explosion but don’t want to assign a part but rather use a position.
I decided to add this myself, although it seems kind of weird to have an EmitterObject and be able to emit at a position.
Here's the things I added/changed
Added this below the “Emit” function:
function self:EmitAtPosition(Amount, Position)
local Properties = {}
local Sav = Emit(Amount, Position)
for i, v in pairs(Sav) do
Properties[i] = v
end
for part, pops in pairs(Properties) do
for name, val in pairs(pops) do
part[name] = val
end
end
end
I changed the local function “Emit” to this. Added an optional parameter of position where it’ll use it if not nil:
local function Emit(Rate, Position) -- Position is optional
local Tabel = {}
for i = 1, Rate do
Index += 1
local New = {}
if #Cachce > 0 then
New.Part = table.remove(Cachce, 1)
else
New.Part = self.Part:Clone()
end
New.Part.CFrame = self.EmmiterObject.CFrame
New.Part.CanCollide = false
New.Part.Anchored = true
New.Part.Locked = true
New.Part.Parent = self.Folder
New.LifeTime = mat.random(self.LifeTime.Min * 1000, self.LifeTime.Max * 1000) / 1000
New.Velocity = Vector3.zero
local SpreadX = self.Spread.X * 10
local SpreadY = self.Spread.Y * 10
New.Velocity = ((self.EmmiterObject.CFrame * CFrame.Angles(math.rad(math.random(-SpreadX, SpreadX)/10), math.rad(math.random(-SpreadY, SpreadY)/10), 0)).LookVector * mat.random(self.Speed.Min * 1000, self.Speed.Max * 1000) / 1000) + (self.EmmiterObject.AssemblyLinearVelocity * self.InheritSpeed)
local EmiCFrame = self.EmmiterObject.CFrame
local Size = self.EmmiterObject.Size
New.Pos = Position or EmiCFrame.Position + EmiCFrame.RightVector * math.random(-10000, 10000) / 20000 * Size.X + EmiCFrame.UpVector * math.random(-10000, 10000) / 20000 * Size.Y + EmiCFrame.LookVector * math.random(-10000, 10000) / 20000 * Size.Z
New.Part.Position = New.Pos
New.CamLastTime = true
New.Delta = 0
table.insert(Particles, 1, New)
Index %= 12
if self.OnSpawn then
Tabel[New.Part] = self:OnSpawn(New.Pos, New.Velocity, 1)
end
end
return Tabel
end
If i were to Emit particles at a certain position i would just change the position of the emitter. But if you like to do it that way, i will probably add this feature when i will be adding new emitter shapes rather than just using blocks. I am kinda happy that you understood the code because it is a totall mess
I tried the Demo Place and it ran all tests at NASA settings getting 60fps without unlocking on a i5-12400 + GTX1030 (ouch). I will try with our awful tablet tomorrow to see how badly that does.
Amazingly cool module and I will try to add it in to one of our projects soon.
Woah, we hit 2k views! I am really happy that people like my module.
Here is my test
PC:
CPU - AMD A8-7410 with Radeon R5
GPU - AMD R5 M330
RAM - 8 GB
Display -1366 x 768
20 fps - medium
9 fps - NASA
10 fps - rain
1 GB RAM used
Honor 9x (phone)
The quality is poor to match the max file size
i think fps 5-10 - medium
I really liked the rain, it looks cool, but it requires a lot of performance
I am always returned with:
Property Instance.Parent is not safe to write in parallel
When using the Emitter:OnCollision()
Code:
function Emitter:OnCollision()
local sound = Instance.new('Sound')
sound.Parent = script
sound.SoundId = 'rbxassetid://6895079853'
sound:Play()
game.Debris:AddItem(sound, sound.TimeLength)
end
Any reason why this is? I know it has something to do with the threading but I’m not too experienced in any of that.
Dont call that method in a non synchronized thread. (So not in a ConnectParralel event or after calling task.desynchornize().
I no spell good btw.
So that you guys know. I have to take a break from looking at screens for a month so i won’t be able to reply to your messages. It might be actually shorter than month or longer.
Wow this is pretty cool. I instantly clicked this because I made a similar albeit more simplified version back in secondary. It’s like barely 100 lines (excluding the typecasting) Introducing BasepartEmitter and ViewportEmitter - #8 by koziahss
Although, it seems like your module mainly focuses on specific particle properties like wind and fluid and does all the physics manually which is impressive.
Also, take your break man. Everyone needs it