What do I want to achieve? I want to have this light I made flicker while it’s on according to a sound I have (I know this works so far), but when the light is off it doesn’t change (it just stays off with no properties changed).
What is the issue? I think I have multiple issues. I’m running an if statement inside a RunService.Heartbeat function. I did this because I want the light to be constantly updated, but the start (on) or stop (off) functions to run once and have the RunService function just wait until the lightStatus value has changed. The lightStatus value changes based on the light’s switch being flicked on or off, on being true while off being false.
What solutions have I tried so far? I tried searching up some solutions but couldn’t really find anything to help me. I always get stuck in a loop inside a loop waiting on each other combo a lot and always get stuck so I thought this would also be a good time to learn how to stop doing that.
This script below in in a local script called “FlickeringLightScript” inside StarterPlayerScripts.
If I need to state any more details I would be more than happy to.
My Code:
local RunService = game:GetService("RunService")
local Light = workspace.Office.Light.Bulb.SpotLight
local Sound = workspace.Office.Light.FlickeringLightSound
local originalAngle = Light.Angle
local originalTransparency = Light.Parent.Transparency
local lightSwitch = workspace.Office:WaitForChild("Lightswitch")
local Switch = lightSwitch:WaitForChild("Switch")
local Main = lightSwitch:WaitForChild("Main")
local lightPrompt = Main:WaitForChild("LightSwitchPrompt")
local lightSound = Main:WaitForChild("LightSwitchSound")
local lightStatus = true
local function start()
Sound.Looped = true
Sound:Play()
Light.Parent.Material = Enum.Material.Neon
Light.Enabled = true
repeat
local currentLoudness = Sound.PlaybackLoudness
Light.Angle = Light.Angle - currentLoudness * 5
Light.Parent.Transparency = Light.Parent.Transparency + currentLoudness / 10
wait(0.05)
Light.Angle = originalAngle
Light.Parent.Transparency = originalTransparency
until lightStatus == false
end
local function stop()
Sound.Looped = false
Sound:Stop()
Light.Parent.Material = Enum.Material.SmoothPlastic
Light.Parent.Transparency = 0
Light.Enabled = false
end
RunService.Heartbeat:Connect(function()
if lightStatus == true then
start()
-- I do not know what to do here.
else
stop()
-- I do not know what to do here.
end
end)
lightPrompt.Triggered:Connect(function()
lightSound:Play()
if lightStatus == true then
lightStatus = false
Switch.Orientation = Vector3.new(55, 180, 180)
lightPrompt.ActionText = "Turn Lights On"
else
lightStatus = true
Switch.Orientation = Vector3.new(35, 0, 0)
lightPrompt.ActionText = "Turn Lights Off"
end
end)
Thank you for your help or even your time reading this!
So, you want the light to flicker while its on, and you want the heartbeat to stop while its off?
When the player clicks the switch to turn it on, connect the heartbeat and store it into a variable, when the player clicks to turn it off, disconnect the variable (disconnecting the heartbeat) so the heartbeat stops.
Use the heartbeat steps to change the properties of the flickering
I’m sorry, I don’t think I am following. I have a rough understanding of what you are saying, but I am having trouble incorporating your solution into my script.
Are you saying something along the lines of:
local example
...
example = RunService.Heartbeat:Connect()
Ok, I read your script, and seems like you want the light to fluctuate based on the PlaybackLoudness of the sound, sorry I didnt notice that.
Well, its almost the same process, you’ll be using the heartbeat to read the loudness of the sound, and change the light properties depending on that right?
So, when player turns on the light, you connect the heartbeat, letting it changing the properties of the light by reading the loudness of the sound, when player turns off the light, you disconnect the heartbeat.
Something like this, just need to reference and adjust the properties of the light and sound in the heartbeat, Im gonna make a test too
local RS = game:GetService("RunService")
local HeartBeatConn
local switch = false
game.Workspace.Part.ProximityPrompt.Triggered:Connect(function()
if not switch then
switch = true
HeartBeatConn = RS.Heartbeat:Connect(function()
print("flickering")
-- Need to reference the light and sound properties
Light.Angle = Light.Angle - currentLoudness * 5
Light.Parent.Transparency = Light.Parent.Transparency + currentLoudness / 10
end)
else
switch = false
HeartBeatConn:Disconnect() -- stop the heartbeat updating
end
end)
Thank you for that suggestion, although I made that post lol. That is not quite the same issue I am having currently, but thank you again for the help.
Isn’t it?
As stated, just use one function to turn the light off, and stop the Heartbeat loop.
Use the other function to do the exact same as you were doing the first time.
Im using this, and the light flickers based on the PLaybackloudness of the sound, updated by the heartbeat, kinda going on rhythm, but idk if thats what you looking for:
local RS = game:GetService("RunService")
local HeartBeatConn
local switch = false
local Light = game.Workspace:WaitForChild("Light"):WaitForChild("SurfaceLight")
local Sound = game.Workspace:WaitForChild("Sound"):WaitForChild("Sound")
game.Workspace.Part.ProximityPrompt.Triggered:Connect(function()
if not switch then
switch = true
Sound:Play()
HeartBeatConn = RS.Heartbeat:Connect(function()
print("flickering")
Light.Angle = 0.18 * Sound.PlaybackLoudness
end)
else
switch = false
Sound:Stop()
HeartBeatConn:Disconnect()
end
end)
Explain more about whats your goal. I understand you want the light to flicker at the rhythm of music by changing the Light.Angle based on the Playbackloudness
So with this script here I believe we are getting closer to what I would like. The light and switch are both on by default (right when you join the game they are on), this is a one player game so no need to worry about how this looks on the server side or anything. Anyway, this script below will work if the lights were off by default, but they aren’t. I need the script to run the flicker function I guess until the player turns the light off, once they do, then this if statement would work instead. Does that makes sense? Loop first, then once the lights go out it waits for the Proximity prompt and does the if statement inside of that function.
Here’s the script:
local RunService = game:GetService("RunService")
local Light = workspace.Office.Light.Bulb.SpotLight
local Sound = workspace.Office.Light.FlickeringLightSound
local originalAngle = Light.Angle
local originalTransparency = Light.Parent.Transparency
local lightSwitch = workspace.Office:WaitForChild("Lightswitch")
local Switch = lightSwitch:WaitForChild("Switch")
local Main = lightSwitch:WaitForChild("Main")
local lightPrompt = Main:WaitForChild("LightSwitchPrompt")
local lightSound = Main:WaitForChild("LightSwitchSound")
local HeartBeatConn
local switch = true
lightPrompt.Triggered:Connect(function()
lightSound:Play()
if switch == true then
switch = false
Sound.Looped = true
Sound:Play()
Light.Parent.Material = Enum.Material.Neon
Light.Enabled = true
Switch.Orientation = Vector3.new(55, 180, 180)
lightPrompt.ActionText = "Turn Lights On"
HeartBeatConn = RunService.Heartbeat:Connect(function()
print("flickering")
-- Need to reference the light and sound properties
local currentLoudness = Sound.PlaybackLoudness
Light.Angle = Light.Angle - currentLoudness * 5
Light.Parent.Transparency = Light.Parent.Transparency + currentLoudness / 10
wait(0.05)
Light.Angle = originalAngle
Light.Parent.Transparency = originalTransparency
end)
else
switch = true
Switch.Orientation = Vector3.new(55, 180, 180)
lightPrompt.ActionText = "Turn Lights On"
HeartBeatConn:Disconnect() -- stop the heartbeat updating
end
end)
Then the only issue now, is that light is on when player joins?
And you want to run the heartbeat, the sound play, flickering etc, to run since the start? and when player clicks to turn off, stop the heartbeat, etc, when player activate prompt again, activate light, music stuff again? And using that script?
Just change some variables and run the function on first script run
local RunService = game:GetService("RunService")
local Light = workspace.Office.Light.Bulb.SpotLight
local Sound = workspace.Office.Light.FlickeringLightSound
local originalAngle = Light.Angle
local originalTransparency = Light.Parent.Transparency
local lightSwitch = workspace.Office:WaitForChild("Lightswitch")
local Switch = lightSwitch:WaitForChild("Switch")
local Main = lightSwitch:WaitForChild("Main")
local lightPrompt = Main:WaitForChild("LightSwitchPrompt")
local lightSound = Main:WaitForChild("LightSwitchSound")
local HeartBeatConn
local switch = false
local function HandleLight()
if not switch then
switch = true
Sound.Looped = true
Sound:Play()
Light.Parent.Material = Enum.Material.Neon
Light.Enabled = true
Switch.Orientation = Vector3.new(55, 180, 180)
lightPrompt.ActionText = "Turn Lights On"
HeartBeatConn = RunService.Heartbeat:Connect(function()
print("flickering")
-- Need to reference the light and sound properties
local currentLoudness = Sound.PlaybackLoudness
Light.Angle = Light.Angle - currentLoudness * 5
Light.Parent.Transparency = Light.Parent.Transparency + currentLoudness / 10
wait(0.05)
Light.Angle = originalAngle
Light.Parent.Transparency = originalTransparency
end)
else
switch = false
Switch.Orientation = Vector3.new(55, 180, 180)
lightPrompt.ActionText = "Turn Lights On"
HeartBeatConn:Disconnect() -- stop the heartbeat updating
end
end
lightPrompt.Triggered:Connect(HandleLight)
HandleLight()
So the light is on and flickering when I join the game, but now the light switch doesn’t work. By that I mean it doesn’t turn off the flickering light.
You sure you are not mixing the switch value? double check, add some prints when player triggers the prompt, let me check. In my test is working normally
Here’s what I changed: (changed “switch” to “lightStatus” to avoid confusion, also added the print(“Runnign”))
local RunService = game:GetService("RunService")
local Light = workspace.Office.Light.Bulb.SpotLight
local Sound = workspace.Office.Light.FlickeringLightSound
local originalAngle = Light.Angle
local originalTransparency = Light.Parent.Transparency
local lightSwitch = workspace.Office:WaitForChild("Lightswitch")
local Switch = lightSwitch:WaitForChild("Switch")
local Main = lightSwitch:WaitForChild("Main")
local lightPrompt = Main:WaitForChild("LightSwitchPrompt")
local lightSound = Main:WaitForChild("LightSwitchSound")
local HeartBeatConn
local lightStatus = false
local function HandleLight()
print("Running")
if not lightStatus then
lightStatus = true
Sound.Looped = true
Sound:Play()
Light.Parent.Material = Enum.Material.Neon
Light.Enabled = true
Switch.Orientation = Vector3.new(55, 180, 180)
lightPrompt.ActionText = "Turn Lights On"
HeartBeatConn = RunService.Heartbeat:Connect(function()
print("flickering")
-- Need to reference the light and sound properties
local currentLoudness = Sound.PlaybackLoudness
Light.Angle = Light.Angle - currentLoudness * 5
Light.Parent.Transparency = Light.Parent.Transparency + currentLoudness / 10
wait(0.05)
Light.Angle = originalAngle
Light.Parent.Transparency = originalTransparency
end)
else
lightStatus = false
Switch.Orientation = Vector3.new(55, 180, 180)
lightPrompt.ActionText = "Turn Lights On"
HeartBeatConn:Disconnect() -- stop the heartbeat updating
end
end
lightPrompt.Triggered:Connect(HandleLight)
HandleLight()
So I ran a few test. The light works when you join, but when you flick the switch the light stops flickering but the light is still on and the audio is still playing. The light switch doesn’t move to the off position either.
There are many details in your script. First the idea of using the heartbeat would be for not using the wait(0.05).
And the way you are changing the light parameters “based” on the Playbackloudness causes the light to have an angle of 0. and stuff that makes the light not really showing
When the heartbeat stops you are not stopping the sound playing too.