Metal Detector not working?

I’m trying to make a metal detector that beeps the closer you are to a scrap. It won’t play any sound and won’t print anything either. I also need help figuring out how to make the beep sound play faster when the player is close.

LocalScript:

local target = script.Parent.Handle
local range = 2048
local equipped
local closest

local function FindClosest()
	for _, scrap in ipairs(workspace.Scraps:GetChildren()) do
		local distance = (target.Position - scrap.Position).Magnitude

		if distance < range then
			range = distance
			closest = scrap
		end
		--how do i make it beep faster if closer
		target.beep:Play()
	end
end

script.Parent.Equipped:Connect(function()
	equipped = true
end)

script.Parent.Unequipped:Connect(function()
	equipped = false
end)

while equipped do
	task.wait(1)
	FindClosest()
end

The while loop at the bottom will never start because equipped will be false as soon as the script begins.

There are multiple ways to go about doing this, but here’s a very basic method:

local players = game:GetService("Players") --you can put this with your other locals
while true do
	script.Parent.Equipped:Wait() --wait for tool equipped event
	while players.LocalPlayer.Character == script.Parent.Parent do --while tool is in character (equipped)
		FindClosest()
		task.wait(1)
	end
end
3 Likes

Exactly this.

It’s also a bad way to handle tools in the first place. You already have functions that connect and disconnect with equipped and unequipped, just handle the logic / the while loop in those instead.

You’re going to have issues with the findclosest function too as it doesn’t find the closest, but instead finds everything within range and plays the beep sound.

1 Like

As the last few posts said. Since you are doing while equipped do, it runs immediately after the player gets the tool and stops since its not equipped, ending the loop forever.

Instead of doing that I would use heartbeat since you also want to change the playback speed of the sound. Something like this:

local RunService = game:GetService("RunService")
local Tool = script.Parent
local Handle = Tool.Handle
local Range = 128
local HeartbeatConnection = nil

function FindClosest(DeltaTime)
	local ClosestScrap
	local ClosestScrapDistance
	
	for _, Scrap in ipairs(workspace.Scraps:GetChildren()) do
		local ScrapDistance = (Scrap.Position - Handle.Position).Magnitude
		
		if ScrapDistance > Range then
			continue
		end
		
		if not ClosestScrapDistance or ScrapDistance < ClosestScrapDistance then
			ClosestScrapDistance = ScrapDistance
			ClosestScrap = Scrap
		end
	end
	
	if not ClosestScrap then
		Handle.beep.PlaybackSpeed = 0
	else
		Handle.beep.PlaybackSpeed = 1 - (ClosestScrapDistance / Range) -- You can set it to x - (ClosestScrapDistance / Range), x being the playback speed you want it to be at if the distance between the scrap and the locator is 0
	end
end

Tool.Equipped:Connect(function()
	Handle.beep:Play()
	HeartbeatConnection = RunService.Heartbeat:Connect(FindClosest) -- Start a new heartbeat connection
end)

Tool.Unequipped:Connect(function()
	Handle.beep:Stop()
	HeartbeatConnection:Disconnect() -- Close the connection on unequip
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.