Fade Out effect for a song

Hello! I am trying to make a fade-out effect for a music playlist (the playlist isn’t pre-defined.) Whenever each song in the playlist is nearing its end, I want it to fade out. How would I accomplish this? I’ve tried using a while loop and constantly using the TimeLength and TimePosition property in a sound to check if it’s nearing its end, but that hasn’t worked. Is there a good way to do this? (Please note I am currently using Sound.Ended:Wait() to know when the song ends, but I want it to fade out instead and run code after that fade-out is complete.)

3 Likes

So, you would have to do something like this:

local fade_start = 3 --//Time from ending to start fading away

while wait(.1) do
if Sound.TimeLength = Sound.TimeLength - fade_start then
--//Fade away with slowly lowering the volume.
end
end

Untested and written on mobile. When I get the chance I will revise and test it, but hopefully you got the basic idea.

This will make the FadeOut function run multiple times.

Heres what I came up with:

local RunService = game:GetService("RunService")
local Sound = path.to.Sound --Your Sound
local FadeTime = 3
local Fading = false

function FadeOut()
    local Ticks = FadeTime * 10
    for i = 1, Ticks do
        Sound.Volume = 0.5 - (0.5 * (i / Ticks))
        wait(0.1)
   end
    Fading = false
end

RunService.HeartBeat:Connect(function()
    if Sound.TimePosition >= Sound.TimePosition - FadeTime and not Fading then
        Fading = true
        FadeOut()
    end
end)

untested too

2 Likes
local tweenService = game:GetService("TweenService")

local fadeStart = 3 -- The amount of seconds subtracted from the length of the song before the fade starts.
local fadeLength = 3 -- The amount of time it takes for the fade to finish.

music:GetPropertyChangedSignal("TimePosition"):Connect(function()
	if music.TimePosition >= music.TimeLength - fadeStart then
		tweenService:Create(music, TweenInfo.new(fadeLength), {Volume = 0}):Play()
	end
end)
3 Likes

Why don’t you just use TweenService when it reaches a certain distance before the end of the song instead of constantly while looping it?

local FadeTime = 5

Sound.Changed("TimePosition"):Connect(function()
    if Sound.TimePosition = Sound.TimeLenth - FadeTime then
        game:GetService("TweenService"):Create(Sound, TweenInfo.new(FadeTime), {
            Volume = 0
        }):Play()
       Sound.Ended:Wait()
       Sound.Volume = .5
    end
end)
2 Likes

Isn’t that still technically constantly looping? It’s practically just a while wait(1) instead.

Only when the property is changed. If the song is paused this will not be firing constantly.
Also I noticed both of them compared TimeLength or TimePosition to itself instead of to each other just right now.

Hm. Didn’t think of it that way. I tend to find a mathematical way before a simple way lol

1 Like

By the way, I edited my solution. And I also noticed that the TimeLength in the if statement are comparing each other too, so I fixed what @SpiralGaia had originally posted. (Fade Out effect for a song - #2 by SpiralAPI)

2 Likes

I don’t know why this isn’t a built in feature of Sound. It should be. Anyway this function seems to work well to fade in or out:

local function fadeSound(sound, targetVolume, duration)
	local Tween = game.TweenService:Create(sound, TweenInfo.new(duration, Enum.EasingStyle.Linear), {Volume = targetVolume})
	--assume we want to play the sound and ramp up folume if target > 0
	if targetVolume > 0 then
		sound.Volume = 0
		sound:Play()
		Tween:Play()
	else
		Tween:Play()
		Tween.Completed:Wait()
		sound:Stop()
	end
end

So to fade in a sound slowly over 2 seconds do:

fadeSound(mysound, 1, 2)

To fade out a sound (vs Stop) slowly over 2 seconds do this:

fadeSound(mysound, 0, 2)
1 Like