How can I make the audio play when the player isn't near any light sources and stop if the player is near a light sources?

Hello, I am currently working on a horror game where the player will become insane if they don’t stand near any light sources. So I want to make the audio play when the player isn’t near any light sources and stop when the player is near a light source (above). I asked the same question on a discord server and someone told me to use raycast but I do not know how to use it and how it works. I will be more than appreciate if you help me solve this out ( Sorry my grammar is terrible)

You could get the distance from the player to all of the light sources and compare it to some value. Stop the sound if a player is within range of any light source or play it otherwise.

-- The distance (in studs) threshold to enable the sound/insanity
local INSANITY_DISTANCE = 50
local lightSources = -- path to lights 
local insaneSound = -- path to sound
local player = game.Players.LocalPlayer

local function checkPlayerInsanity()
	-- Loop over all light sources
	for _, light in pairs(lightSources) do
		-- Get the distance from the light source to the player and compare it to the range
		if player:DistanceFromCharacter(light.Position) > INSANITY_DISTANCE then
			-- Enable the sound/insanity if they are outside of the range
			insaneSound:Play()
		else 
            -- Else, stop the sound
			insaneSound:Stop()
		end
	end
end

-- You can hook up the above function to run every x seconds or on every server tick, e.g.
game:GetService("RunService").Heartbeat:Connect(checkPlayerInsanity)
2 Likes

There’s a function intended just for that, DistanceFromCharacter. I’d recommend implementing that in order to make things much simpler and easier.

2 Likes

I’ve been on roblox for years and this is the first time I’m seeing this, wow :joy: Thank you!

2 Likes

The answer to that is to scan everything from workspace and use DistanceFromCharacter as Araxon said, and check if it’s far or near the player.

Otherwise if you don’t know how to script it or you just don’t want to waste time scripting it then here’s the code.

LocalScript (Tested)
local RunService = game:GetService("RunService")
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local sound = ... -- locate your sound
local maxDist = 100




RunService.Heartbeat:Connect(function()

	for i, v in pairs(workspace:GetDescendants()) do -- scans through workspace 
		if not v:IsDescendantOf(char) 
			and v:FindFirstChildWhichIsA("Light")
			and v:IsA("BasePart") then

			local lightPos = v.Position
			local dist = plr:DistanceFromCharacter(lightPos) -- get dist
			if dist < maxDist then
				if sound.IsPlaying == true then
					-- detect if it's playing
					sound:Stop()
				end


			elseif dist > maxDist then
				if sound.IsPlaying == false then
					-- detects if it's not playing, also fixes the bug 
					-- that doesn't play the sound as expected
					sound:Play()
				end

			end
		end
	end

end)
1 Like

Thank you I really appreciate it

Thank you very much I really appreciate it

1 Like

I think there’s something wrong with script 3, the sound didn’t play either can you help me one more time?

It’s supposed to be in a localscript, and recommended to be placed in StarterPlayerScripts.

that fixed script 3 but the sound didn’t play

Are there any errors at the moment?

I can’t find any errors in output about the script

This should work (I also haven’t test this, and It worked for me because I only made detect if 1 light is near or not)

local RunService = game:GetService("RunService")
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local sound = workspace.Heartbeat
local maxDist = 100


local lights = {}

RunService.Heartbeat:Connect(function()

	for i,v in pairs(workspace:GetDescendants()) do -- scans through workspace 
		if not v:IsDescendantOf(char) 
			and v:FindFirstChildWhichIsA("Light")
			and v:IsA("BasePart") then
			local dist = plr:DistanceFromCharacter(v.Position)
			table.insert(lights,dist)
		end
	end

	table.sort(lights, function(a,b)
		return a<b
	end)

	local dist = lights[1]
	if dist < maxDist then
		if sound.IsPlaying == true then
			-- detect if it's playing
			sound:Stop()
		end


	elseif dist > maxDist then
		if sound.IsPlaying == false then
			-- detects if it's not playing, also fixes the bug 
			-- that doesn't play the sound as expected
			sound:Play()
		end

	end

    lights = {}

end)


I think there is something wrong with script 27

Apologies on responding late because i had to gtg that time.

Can I see the lights in explorer? Is the lighter tool the only light source in game?

Replace this

if not v:IsDescendantOf(char) 
	and v:FindFirstChildWhichIsA("Light")
	and v:IsA("BasePart") then
	local dist = plr:DistanceFromCharacter(v.Position)
	table.insert(lights,dist)
end

To

if v:FindFirstChildWhichIsA("Light")
	and v:IsA("BasePart") then
	local dist = plr:DistanceFromCharacter(v.Position)
	table.insert(lights,dist)
end

I think there’s something wrong with script 26 now

I have realized there was only one light, got it fixed by detect if there are more than 1 lights in order to use table.sort.

Try this

local RunService = game:GetService("RunService")
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local sound = workspace.Heartbeat
local maxDist = 100


local lights = {}

RunService.Heartbeat:Connect(function()

	for i,v in pairs(workspace:GetDescendants()) do -- scans through workspace 
		if v:FindFirstChildWhichIsA("Light")
			and v:IsA("BasePart") then
			local dist = plr:DistanceFromCharacter(v.Position)
			table.insert(lights,dist)
		end
	end

    local totalLights = 0
	for i,v in pairs(lights) do
        totalLights += 1 -- =+ if there is an error here
    end

    if totalLights > 1 then
        table.sort(lights, function(a,b)
	       	return a<b
        end)
    end

	local dist = lights[1]
	if dist < maxDist then
		if sound.IsPlaying == true then
			-- detect if it's playing
			sound:Stop()
		end

	elseif dist > maxDist then
		if sound.IsPlaying == false then
			-- detects if it's not playing, also fixes the bug 
			-- that doesn't play the sound as expected
			sound:Play()
		end
	end

    lights = {}

end)

There might be something wrong in the “if dist < maxDist then”

Ok hold on, I’m now going to test this script and fix this.

1 Like