Collapse Sidebar




The Lifetime property defines the maximum and minimum ages a newly emit particle will. When a particle is emit, a random lifetime is chosen uniformly. Lifetimes are stored on a per-particle basis, so if this value is changed, existing particles will stay “alive” until their randomly chosen lifetime is lived. The bounds for this property should be in the range [0, 20]. By default, ParticleEmitters will have a lifetime of 5 to 10 seconds. A lifetime of 0 will prevent particles from being emit in the first place.

it is important to pick a sensible Lifetime and ParticleEmitter/Rate so that you don’t have too many particles being rendered at once. Long lifetimes and high emission rates are a quick way to cause performance issues. If you need many particles, pick a balance of lifetime and rate. To instantly remove any presently emit particles (perhaps ones with absurdly long lifetimes), you can call ParticleEmitter/Clear.

Code Samples

Creating a Particle Emitter from Scratch

This rather lengthy code sample shows how every property of a ParticleEmitter can be set, including DataType/NumberRange, DataType/NumberSequence and DataType/ColorSequence properties. Below is how the ParticleEmitter should after every property is set. Try playing around with the different properties to customize how the effect looks!

The final product

local emitter = Instance.new("ParticleEmitter")
-- Number of particles = Rate * Lifetime
emitter.Rate = 5 -- Particles per second
emitter.Lifetime = NumberRange.new(1,1) -- How long the particles should be alive (min, max)
emitter.Enabled = true 

-- Visual properties
emitter.Texture = "rbxassetid://1266170131" -- A transparent image of a white ring
-- For Color, build a ColorSequence using ColorSequenceKeypoint
local colorKeypoints = {
	-- API: ColorSequenceKeypoint.new(time, color)
	ColorSequenceKeypoint.new( 0, Color3.new(1, 1, 1)),  -- At t=0, White
	ColorSequenceKeypoint.new(.5, Color3.new(1, .5, 0)), -- At t=.5, Orange
	ColorSequenceKeypoint.new( 1, Color3.new(1, 0, 0))   -- At t=1, Red
emitter.Color = ColorSequence.new(colorKeypoints)
local numberKeypoints = {
	-- API: NumberSequenceKeypoint.new(time, size, envelop)
	NumberSequenceKeypoint.new( 0, 1);    -- At t=0, fully transparent
	NumberSequenceKeypoint.new(.1, 0);    -- At t=.1, fully opaque
	NumberSequenceKeypoint.new(.5, .25);  -- At t=.5, mostly opaque
	NumberSequenceKeypoint.new( 1, 1);    -- At t=1, fully transparent
emitter.Transparency = NumberSequence.new(numberKeypoints)
emitter.LightEmission = 1 -- When particles overlap, multiply their color to be brighter
emitter.LightInfluence = 0 -- Don't be affected by world lighting

-- Speed properties
emitter.EmissionDirection = Enum.NormalId.Front -- Emit forwards
emitter.Speed = NumberRange.new(0, 0) -- Speed of zero
emitter.Drag = 0 -- Apply no drag to particle motion
emitter.VelocitySpread = NumberRange.new(0, 0)
emitter.VelocityInheritance = 0 -- Don't inherit parent velocity
emitter.Acceleration = Vector3.new(0, 0, 0)
emitter.LockedToPart = false -- Don't lock the particles to the parent 
emitter.SpreadAngle = Vector2.new(0,0) -- No spread angle on either axis

-- Simulation properties
local numberKeypoints2 = {
	NumberSequenceKeypoint.new(0, 0);  -- At t=0, size of 0
	NumberSequenceKeypoint.new(1, 10); -- At t=1, size of 10
emitter.Size = NumberSequence.new(numberKeypoints2)
emitter.ZOffset = -1 -- Render slightly behind the actual position
emitter.Rotation = NumberRange.new(0, 360) -- Start at random rotation
emitter.RotSpeed = NumberRange.new(0) -- Do not rotate during simulation

-- Create an attachment so particles emit from the exact same spot (concentric rings)
local attachment = Instance.new("Attachment", script.Parent)
attachment.Position = Vector3.new(0, 5, 0) -- Move the attachment upwards a little
emitter.Parent = attachment