The issue is, is that, when I try to click the "Play Sound" button, (even on like... 1 hour long sounds) it just immediately changes the text to "Stop Sound" and another microsecond later it changes to "Play Sound" without playing the audio. The things I tried is inside the code block below.
01 | local Module = require(game.StarterGui.eText) |
02 | local btn = script.Parent.Parent.BtnPlay |
03 | local input = script.Parent.Parent.Input |
04 | local sound = workspace.Sound |
05 | local playing = false |
06 |
07 | btn.MouseButton 1 Click:Connect( function () |
08 | if playing = = false then -- (<-- Which is this one) I tried to make it easier for the script to understand but didn't work, the previous one was |
09 | -- "if not playing then" |
10 | sound.SoundId = "rbxassetid://" .. input.Text |
11 | sound:Play() |
12 |
13 | Module.ApplyText(btn, "Stop Sound" ) |
14 | playing = true |
15 | wait(sound.TimeLength) -- If I put it to 8 seconds, the sound will play for 8 seconds but |
i could be wrong but it could be because the sound is not yet loaded when you index it's TimeLength
(If it's not loaded it will return 0), that's because roblox must first access it's servers and get product info of the sound and then only configure the sound. You have 2 solutions here, GetPropertyChangedSignal or Sound.Ended.
GetPropertyChangedSignal
This is a signal that fires when given property of instance changes, in your case you can wait until the sound's length is not 0:
01 | ... |
02 | sound.SoundId = "rbxassetid://" .. input.Text |
03 | sound:Play() |
04 |
05 | Module.ApplyText(btn, "Stop Sound" ) |
06 | playing = true |
07 |
08 | Sound:GetPropertyChangedSignal( 'TimeLength' ):Wait() |
09 | --/Will wait until this event fires, it will fire when TimeLength |
10 | --\of this sound changes, i can't be sure that this is realiable |
11 | --\so i would better do more checks or use the second method |
12 |
13 | wait(Sound.TimeLength) |
14 |
15 | sound:Stop() |
16 | ... |
Sound.Ended
An event of Sound
which fires when it ends, in your case you would use it instead of wait
and yield until the event fires:
1 | ... |
2 | sound.SoundId = "rbxassetid://" .. input.Text |
3 | sound:Play() |
4 |
5 | Module.ApplyText(btn, "Stop Sound" ) |
6 | playing = true |
7 |
8 | sound.Ended:Wait() |
9 | ... |
That way you can also get rid of Sound:Stop()
and i personally prefer this method over the first one.
just put the sound inside the gui and the play and stop in different buttons like:
1 | function Song() |
2 | local ID = script.Parent.Parent.id.Text |
3 | local sound = script.Parent.Parent.Parent.Music |
4 | Sound.SoundId = 'rbxassetid://' .. ID |
5 | Sound:Play() |
6 | end |
7 | script.Parent.MouseButton 1 Click:connect(Song) |
and then
1 | function Stop() |
2 | script.Parent.Parent.Parent.Sound:Stop() |
3 | end |
4 | script.Parent.MouseButton 1 Click:connect(Stop) |
-side note make sure the sounds in the gui and the buttons are in a frame id is a text box! :)