intervalactive = GetFloatParam("intervalactive",-1) intervalpause = GetFloatParam("intervalpause",-1) broken = false function init() origin = FindLocation("origin") local origin_transform = GetLocationTransform(origin) local origin_pos = origin_transform.pos local direction = FindLocation("direction") local direction_transform = GetLocationTransform(direction) local direction_pos = direction_transform.pos particleshape = FindShape("particleshape") local particleshape_transform = GetShapeWorldTransform(particleshape) local_origin = TransformToLocalPoint(particleshape_transform, origin_pos) local_direction = TransformToLocalPoint(particleshape_transform, direction_pos) interval = 0 pause = false broken = false end --Helper to return a random vector of particular length function rndVec(length) local v = VecNormalize(Vec(math.random(-100,100), math.random(-100,100), math.random(-100,100))) return VecScale(v, length) end --Helper to return a random number in range mi to ma function rnd(mi, ma) return math.random(1000)/1000*(ma-mi) + mi end --Update function handles smoke emission --It is important to put it in update and not tick for constant emission rate function update(dt) if broken then return end local particleshape_transform = GetShapeWorldTransform(particleshape) local world_origin = TransformToParentPoint(particleshape_transform,local_origin) local world_direction = TransformToParentPoint(particleshape_transform,local_direction) local ct = GetCameraTransform() local t = GetLocationTransform(origin) if VecLength(VecSub(t.pos, ct.pos)) > 30 then return end if intervalactive ~= -1 then interval = interval + dt if pause and interval > intervalpause then pause = not pause interval = 0 end if not pause and interval > intervalactive then pause = not pause interval = 0 end if pause then return end end if particleshape ~= 0 then if not broken and IsShapeBroken(particleshape) then broken = true end end local pos = world_origin--t.pos local dir = VecSub(world_direction,world_origin) -- THINGS YOU CAN TWEAK -- radius, particle spawn randomness from origin in meters local radius = 0.1 -- life, particle lifetime in seconds local life = rnd(1,3) -- amount of particles emitted every frame local count = 1 -- velocity of the particles local vel = 1 -- particle drag local drag = 0.2 -- particle gravity local gravity = 0.12 -- aplha of the particles, is also affected by the lifetime of the particle local alpha = 0.3 -- Start values for the particle color local start_red = 0.3 local start_green = 0.3 local start_blue = 0.3 -- End values for the particle color local end_red = 0.9 local end_green = 0.9 local end_blue = 0.9 --Set up the particle state ParticleReset() ParticleType("smoke") ParticleRadius(radius) ParticleAlpha(alpha, alpha, "constant", 0.1/life, 0.5) -- Ramp up fast, ramp down after 50% ParticleGravity(gravity * rnd(0.5, 1.5)) -- Slightly randomized gravity looks better ParticleDrag(drag) ParticleColor(start_red, start_green, start_blue, end_red, end_green, end_blue) -- Animating color towards white --Emit particles for i=1, count do --Randomize position slightly. This is important when spawning multiple particles at the same time local p = VecAdd(pos, VecAdd(VecScale(dir, radius), rndVec(radius))) --Randomize velocity slightly local v = VecScale(VecAdd(dir, rndVec(0.2)), vel) --Randomize lifetime local l = rnd(life*0.5, life*1.5) --Spawn particle into the world SpawnParticle(p, v, l) end end