Function creates multiple instances instead of one

What im trying to do
Hello! Currently im working on weapon system and wanted to play sounds when Reload Animation reaches a Keyframae with a sound ID. When Keyframe reached, LocalScript firing RemoteEvent with a SoundID needed to play. Then, Server script should create a Sound instance and insert a sound with a SoundID from RemoteEvent. Simple.

What’s wrong?
Everything works fine. Keyframe reached, Event launched, Sound created. But i noticed, that with each Reload animation, Server script creates more Sound instances than needed (For example, animation have only 3 keyframes with sounds, but script creates 6 or more). Basically, just duplicates them for no reason. (Yes, i set a script to delete old Sound instances)
This
Here is how model looks after multiple reloads. “Temp” is sound instances created by script

Did i look for similar topics?
Yes i did. The first thing i tried is making a debounce. But with a debounce added, script creates only one Sound, when animation have 3 of them. After this, i couldn’t find any solutions

Here is Local Script code

reloadAnim:Play()
reloadAnim.KeyframeReached:Connect(function(key)
	if key:sub(1,4) == "sfx/" then
		local id = key:sub(5)
		local audio = ("rbxassetid://"..id)
		SoundEvent:FireServer(audio)
	end
end)

And here is Server Script code. Which creates sound

local function play_sound(audio)
	local Snd = Instance.new("Sound")
	Snd.Parent = script.Parent.BodyAttach
	Snd.Name = "Temp"
	Snd.SoundId = audio
	Snd.Volume = 0.35
	Snd.RollOffMaxDistance = 65
	Snd.RollOffMinDistance = 5
	Snd:Play()
end


SoundEvent.OnServerEvent:Connect(function(player,audio)
	play_sound(audio)
end)

I will be very thankful if you help me out.

1 Like

Have you tried to use FindFirstChild() in order to find if that sound already exists there?

local function play_sound(audio)
	local Snd = Instance.new("Sound")
    local isThere = script.Parent.BodyAttack:FindFirstChildWhichIsA("Sound")
    if isThere.Name ~= "Temp" then
     Snd.Parent = script.Parent.BodyAttach
	 Snd.Name = "Temp"
	 Snd.SoundId = audio
	 Snd.Volume = 0.35
	 Snd.RollOffMaxDistance = 65
	 Snd.RollOffMinDistance = 5
	 Snd:Play()
    end
end


SoundEvent.OnServerEvent:Connect(function(player,audio)
	play_sound(audio)
end)
2 Likes

Try this

local function play_sound(audio)
	local Snd = Instance.new("Sound")
	Snd.Parent = script.Parent.BodyAttach
	Snd.Name = "Temp"
	Snd.SoundId = audio
	Snd.Volume = 0.35
	Snd.RollOffMaxDistance = 65
	Snd.RollOffMinDistance = 5
	Snd:Play()
    task.wait(snd.TimeLength)
    snd:Destroy()
end
1 Like

Thanks for your reply! It helped me to improve script logic. I modified your script to work properly, and here what i got in the end:

local function play_sound(audio)
	for _, v in ipairs(script.Parent.BodyAttach:GetChildren()) do
		if v.Name == "Temp" then
			if v.SoundId == audio then
				v:Destroy()
			end
		end
	end
	local Snd = Instance.new("Sound")
	Snd.Parent = script.Parent.BodyAttach
	Snd.Name = "Temp"
	Snd.SoundId = audio
	Snd.Volume = 0.35
	Snd.RollOffMaxDistance = 65
	Snd.RollOffMinDistance = 5
	Snd:Play()
end

The script is checking BodyAttach (Parent for all sounds) and looks for Children with the similar ID’s and destroying copies. Might cause some problems, if i use same sound in animation multiple times, but… At least it works! Needs some improvements but this is already a progress!

2 Likes

After days of testing, this script works just fine!
It didn’t solve the problem of Roblox duplicating instances with each cycle, but for my case, it’s enough. thanks everyone for help.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.