Sound.Ended does not work

For some reason, my song isn’t firing the Ended event.

Pasted as is

if not CurrentSong.Looped then -- Not a looped song (plot music)
		print(CurrentSong) -- prints Plot-1
		--// Continue playing plot music
		CurrentSongLoopConnection = CurrentSong.Ended:Connect(function()
			print("Stopped", CurrentSong.Name) -- Never prints
			local SongIndex = string.gsub(CurrentSong.Name, "%D", "")
			print(SongIndex)
			if not SongIndex then return end
			print(tonumber(SongIndex))
			if not tonumber(SongIndex) then return end -- Not a number
			
			local NextIndex = tonumber(SongIndex) < 3 and tonumber(SongIndex) + 1 or 1
			print("Next song is", NextIndex)
			
			local NextSong = Music:FindFirstChild("Plot-" .. NextIndex)
			SoundPlayer.PlayMusic(NextSong)
		end)
	end

As you can see, it prints the Plot-1 on start, which is correct. But even when the song has finished, it does not fire the connection

Why are you naming the function CurrentSongLoopConnection?

1 Like

So I can disconnect is easily

if CurrentSongLoopConnection then
	CurrentSongLoopConnection:Disconnect()
end

Just come to my attention that the event is broken anyway and has been broken for 4 years :confused:

In that case is this the only option?

function playsound(sound)
    sound:Play()
    wait(sound.TimeLength)
end)

So when u call this with
playsound(sound)
code continues after the wait(sound.TimeLength) has waited

I can’t have that, as if I start playing a different song, I need this to be disconnected. I can’t have something yield

then why dont u do this:

local currentsong = nil

function playsound(newsound)
	if currentsong ~= nil then
		if currentsong.Playing == true then
			currentsong:Stop()
		end
	end
	currentsong = newsound
	currentsong:Play()
	wait(currentsong.TimeLength)
end

now when u play new song it checks if theres already playing souns and stops it, then plays the new one

No, cause that then doesn’t get the next song. I have all this weird looking code their for a reason, as it needs to seamlessly transition from a list of 3 songs

			local SongIndex = string.gsub(CurrentSong.Name, "%D", "")

			if not SongIndex then return end

			if not tonumber(SongIndex) then return end -- Not a number
			
			local NextIndex = tonumber(SongIndex) < 3 and tonumber(SongIndex) + 1 or 1
			
			local NextSong = Music:FindFirstChild("Plot-" .. NextIndex)
			SoundPlayer.PlayMusic(NextSong)

How does this line set your CurrentSong variable?

I suspect the issue is that either CurrentSong isn’t actually set to the Sound that’s playing or CurrentSong:Stop() is being called which won’t fire the .Ended event.

u must use sound.Stopped if u want it to fire when stopped

I don’t think

sound.Ended:Connect(function()

picks up when the sound ends, so use:

sound.Ended:Wait()

Sounds have different events for each reason they can be stopped/ended:

local Sound = workspace.Sound 

--if a sound reaches the end of TimePosition and has Sound.Looped set to false
Sound.Ended:Connect(function()
	print("I ended")
end)

--if a sound is manually stopped with Sound:Stop()
Sound.Stopped:Connect(function()
	print("I stopped")
end)

--if instead of Sound:Stop(), Sound:Pause() is used
Sound.Paused:Connect(function()
	print("I got paused")
end)

--if sound.Looped is set to true, this will fire instead(not Sound.Ended)
Sound.DidLoop:Connect(function()
	print("I looped")
end)

--if instead of Sound:Stop(), Sound.Playing = false is used
Sound:GetPropertyChangedSignal("Playing"):Connect(function()
	if not Sound.Playing then 
		print("I stopped with .Playing = false(also applies to Ended, Stopped, Paused)")
	end
end)

--if the sound gets destroyed(wont run if the script is inside the Sound itself)
Sound.AncestryChanged:Connect(function()
	if Sound.Parent == nil then 
		print("I got destroyed")
	end
end)

--will fire even if the script is inside the sound
--didn't find a way to make this check pretty
task.spawn(function()
	while task.wait(.1) do 
		if Sound.Parent == nil then 
			print("I got destroyed")
			break 
		end
	end
end)
1 Like