How to emit a particle without waiting

Hello everyone,

I’ve been looking around on the web for a while but couldn’t find a good solution,
How would I emit a particle without waiting in my code (this is in a local script)

local function emit_killEffect(killEffect)
    local newKillEffect = killEffect:Clone()
	newKillEffect.Position = pos
	newKillEffect.Parent = workspace
	
	task.wait(.5)
	local sfx = newKillEffect:FindFirstChildWhichIsA("Sound")
	if sfx then
		sfx:Play()
	end
	
	for _, att in newKillEffect:GetChildren() do
		for _, particle in att:GetChildren() do
			if particle:IsA("ParticleEmitter") then
				particle:Emit(2)
			end
		end
	end
	task.defer(function()
		task.wait(3)
		newKillEffect:Destroy()
	end)
end

If I remove the wait, sometimes the particles emits before it fully loads making the particle invisible. Adding a task.wait(.5) fixes this issue but creates a weird delay and doesn’t look good, using lower values like task.wait(.1) helps but sometimes the particle still emits before it fully loads, is there any solution to this apart from creating it earlier since I would have to restructure a lot of my code?

Thanks a lot

1 Like

When creating the particle for a second time within the same testing session, does it load immediately? If so, that means it simply takes some time to load the texture => task.wait() is not an efficient solution.

Your best bet would be implementing a loading screen, or just literally anything that calls ContentProvider:PreloadAsync() on the necessary instances to make Roblox preload the assets.

EDIT: On an unrelated note, you don’t have to chain task.wait() with task.defer() to delay the execution on a new thread. You could call task.delay() and it’ll do everything for you.
So like: task.delay(3, newKillEffect.Destroy, newKillEffect)

1 Like

After using the function a few times without the wait, it doesn’t always emit on the second or third time, sometimes it emits sometimes it doesn’t
btw thanks for the tip

Did you call PreloadAsync right before emitting it? Because if so, that’s not the way to go about it. You’re supposed to call it before you even have to use the instance.

like this?
newKillEffect is a part so would it include its children which are attachments and particle emitters

local function emit_killEffect(killEffect)
    local newKillEffect = killEffect:Clone()
    ContentProvider:PreloadAsync({newKillEffect})

	newKillEffect.Position = pos
	newKillEffect.Parent = workspace
	
	local sfx = newKillEffect:FindFirstChildWhichIsA("Sound")
	if sfx then
		sfx:Play()
	end
	
	for _, att in newKillEffect:GetChildren() do
		for _, particle in att:GetChildren() do
			if particle:IsA("ParticleEmitter") then
				particle:Emit(2)
			end
		end
	end
	task.delay(3, function()
		newKillEffect:Destroy()
	end)
end

Yeah that’s what I thought you did - you’re not supposed to use it like this. You’re supposed to call PreloadAsync BEFORE you even have to create the effect. Like, if you call it once you’re already instantiating the effect, it’s too late to do that since it’ll just yield the current thread until the assets load.

It’d have to be called outside of the emit_killEffect function. Assuming that those kill effects are stored somewhere in ReplicatedStorage, preload them all in one go.