Any Way to grab a sound that is in workspace from an object value and then stop it?

Hello! im making a sort of audio log system like bendy and the dark revival. and i want the player to press F to skip the audio if they want to listen to it later. but i have tried alot to grab the sound from the object value. and it just keeps giving me an error. 'attempt to index nil with ‘Stop’, i have no idea what to do. pls help.

script when collecting the tape [only to explain that the object value is linked to the sound] :

script.Parent.Triggered:Connect(function(plr)
local AudioLogFrame = plr.PlayerGui:WaitForChild(“MainGui”).Tape.AudioLog
local AudioLogAuthor = AudioLogFrame.NameBar.NameText

script.Parent.MaxActivationDistance = 0
script.Parent.Parent.Parent.AudioLog_Body.Transparency = 1
script.Parent.Parent.Parent.AudioLog_Body.CanCollide = false
script.Parent.Parent.Parent.AudioLog_PlayButton.Transparency = 1
script.Parent.Parent.Parent.AudioLog_PlayButton.CanCollide = false
script.Parent.Parent.Parent.AudioLog_Reel1.Transparency = 1
script.Parent.Parent.Parent.AudioLog_Reel1.CanCollide = false
script.Parent.Parent.Parent.AudioLog_Reel2.Transparency = 1
script.Parent.Parent.Parent.AudioLog_Reel2.CanCollide = false
AudioLogFrame.Visible = true
AudioLogAuthor.Text = “BLAH BLAH - ???”
workspace.Sounds.Tapes.BlahBlah:Play()
plr.Character:WaitForChild(“CanSkipTape”).Value = true
plr.Character:WaitForChild(“TapePlaying”).Value = workspace.Sounds.Tapes.BlahBlah
workspace.Sounds.Tapes.BlahBlah.Ended:Wait()
AudioLogFrame.Visible = true
plr.Character:WaitForChild(“CanSkipTape”).Value = false
plr.Character:WaitForChild(“TapePlaying”).Value = nil
end)

script that handles the skipping thing [where im having trouble] :

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Uis = game:GetService(“UserInputService”)
local TapeValue = Character:WaitForChild(“TapePlaying”) – the object value
local TapeAudio = nil
local CanSkip = Character:WaitForChild(“CanSkipTape”)
local AudioLogFrame = Player.PlayerGui:WaitForChild(“MainGui”).Tape.AudioLog

Uis.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.F then
if CanSkip.Value == true then
TapeAudio = workspace.Sounds.Tapes:FindFirstChild(TapeValue.Value)
AudioLogFrame.Visible = false
wait(0.05)
TapeAudio:Stop()
wait(0.05)
TapeAudio.Value = nil
CanSkip.Value = false
end
end
end)

here are some images :
image
image
image

so basically you want to stop the audio from playing when a player presses F? or do you want to pause the audio whenever the player pressed F, and then when they Press F again, the music continues?

yes. there will be alot of audios. so i need to make this from an object value. unless i make like 100 values and 100 localscripts, which will not really be that nice.

no. the music will not continue. they will be able to pause using TAB and go to the audio logs section

oh so basically pressing F to skip to another song, is it what you want to achieve?

no no. its like batdr. you pick up an audio log. you listen to it or you can skip it. if you skip it or wait until it ends it will appear in your pause menu. if you want to listen to it again. and then you can do that over and over for each audio log you find

script.Parent.Triggered:Connect(function(plr)
	local AudioLogFrame = plr.PlayerGui:WaitForChild(“MainGui”).Tape.AudioLog
	local AudioLogAuthor = AudioLogFrame.NameBar.NameText

	script.Parent.MaxActivationDistance = 0
	script.Parent.Parent.Parent.AudioLog_Body.Transparency = 1
	script.Parent.Parent.Parent.AudioLog_Body.CanCollide = false
	script.Parent.Parent.Parent.AudioLog_PlayButton.Transparency = 1
	script.Parent.Parent.Parent.AudioLog_PlayButton.CanCollide = false
	script.Parent.Parent.Parent.AudioLog_Reel1.Transparency = 1
	script.Parent.Parent.Parent.AudioLog_Reel1.CanCollide = false
	script.Parent.Parent.Parent.AudioLog_Reel2.Transparency = 1
	script.Parent.Parent.Parent.AudioLog_Reel2.CanCollide = false
	
	
	AudioLogFrame.Visible = true
	AudioLogAuthor.Text = “BLAH BLAH - ???”
	workspace.Sounds.Tapes.BlahBlah:Play()
	task.wait(1) -- // Try to add these

	plr.Character:WaitForChild(“CanSkipTape”).Value = true
	plr.Character:WaitForChild(“TapePlaying”).Value = workspace.Sounds.Tapes.BlahBlah
	task.wait(1) -- // Try to add these

	workspace.Sounds.Tapes.BlahBlah.Ended:Wait()
	task.wait(1) -- // Try to add these

	AudioLogFrame.Visible = true
	plr.Character:WaitForChild(“CanSkipTape”).Value = false
	plr.Character:WaitForChild(“TapePlaying”).Value = nil
end)

Your first script may have been too fast for your other script to read if the values have changed, I suggest to add a wait time, and see if they work.


also, can I know where these 2 scripts are located in the Explorer and where are they parented?

because as your way to reference the bool values it may have been that easy to detect whether it goes true or false or it may have been unable for the 2nd script to listen to it if its too fast.

1 Like

one script is inside a proximity prompt
the other is in starterplayerscripts

also the script works the same. but now the object value loads longer

1 Like

it does everything but not stopping the audio. i might be grabbing the audio in a wrong way? idk
image

1 Like

are you using stringVal for the placement of the audio ID?

plr.Character:WaitForChild(“TapePlaying”).Value = workspace.Sounds.Tapes.BlahBlah

because this part is a bit strange, what are you placing inside the Value that’s probably why its not able to locate the audio.

Try this way:

plr.Character:WaitForChild(“TapePlaying”).Value = workspace.Sounds.Tapes.BlahBlah.SoundId
-- // Assuming that "TapePlaying.Value" here is a StringVal
-- // So you'd need to actually get which Value it will be by referencing ".SoundId" to the other end

One thing as well on the 2nd script, you might want to do this instead:

Uis.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.F then
		if CanSkip.Value == true then
			TapeAudio = workspace.Sounds.Tapes:FindFirstChild(TapeValue.Value)
			AudioLogFrame.Visible = false
			
			if TapeAudio == TapeValue then -- // This will always detect TapeValue's Value
				TapeAudio:Stop()
				TapeAudio.Value = nil
				CanSkip.Value = false
			elseif TapeValue == nil then
				return
			end
			
		end
	end
end)

let me know if this will help you around

1 Like

im using an object value. and the value is the actual audio. not the id

1 Like

but i can try a string value if it would work

1 Like

can I see how the explorer looks like for both ProximityPrompt and PlayerGUI?

uhhh sure why not.
image
image
image

oh also it doesnt stop. it gives me no error. just it doesnt stop the audio

I see, where does the Sound Folder parented to?

to workspace
if you havent noticed by the script

I see, so what you are trying to do with the first script is

trying to put a Value on “TapePlaying” which is assuming the Audio’s ID.

This got me thinking that your TapePlaying = StringValue, that would store the Audio’s ID in it or maybe a bool Value.

So whenever your 2nd Script listens to that, TapeValue returns as 0 or nil or the AudioID because its not the “Sound” Instance.

So whenever you try to press “F” to skip the Sound, it returns a nil because there’s no audio you are trying to Stop. But just literally nil or the TapeValue’s Value itself.

tapeplaying is the actual audio. not the id. since u cant rlly stop an audio id

it used to be an object value. the object value was the audio. i checked when playing. i just need to get the audio somehow from the local script