How do I fix this easy Magnitude script

I am trying to make a simple radiation script which detects if a player is close to one of the bricks inside a folder. If the player is close enough it makes the dosimeter transparent and it plays a clicking sound for now. If you are not close enough to a brick it will print (“stop”) until you are close enough. The problem I have is, that if you come close enough, it will keep printing stop, because you are “not close enough to the other bricks”. This causes the clicking sound to keep starting and ending itself until you leave the area. One weird thing is, that one of the three bricks will work correctly, and stop printing(“stop”), the others don’t. This means, one of the brick works as usual. I hope somebody has an idea how to fix this. Code and video is below
Chernobyl test - Roblox Studio (gyazo.com)

local rs = game:GetService("RunService")
game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char) 
		while rs.Stepped:Wait() do
			for i, v in pairs(workspace.Radiation:GetChildren()) do 
				if v.ClassName == "Part" then
					local humrp = player.Character:WaitForChild("HumanoidRootPart")
					if humrp then
						local pos = humrp.Position - v.Position
						local Magnitude = pos.magnitude

						if Magnitude <= 20 then 
							
							if player.Character:FindFirstChild("Dosimeter") then
								player.Character.Dosimeter.Transparency = 0
								if player.Character.Dosimeter.clicking.Playing == false then
									player.Character.Dosimeter.clicking:Play()
								end
								print(Magnitude)
								print("radiation near")
								break
							end
						else
							player.Character.Dosimeter.clicking:Stop()
							player.Character.Dosimeter.Transparency = 1
						end		
					end
				end
			end
		end
	end)
end)```

Why don’t you do something like where you just put a box around that area, and once they touch it, then use a repeat to check once they have left due to I have found .TouchEnded can be buggy at times. or you could try using .TouchEnded, you may have better luck than I did. By doing this you won’t have to put the stress of repeating itself because what if a player is AFK, it just will make the game laggy for low end devices.

Well yea, but .Touched is too random and buggy for me.

maybe keep track of which brick is closest and run the distance loop for that brick, while also checking if that brick is still the closest brick. when there is a different brick that is closer, change the loop to work with that brick instead

local rs = game:GetService("RunService")
game.Players.PlayerAdded:Connect(function(player)--The player that joined
    player.CharacterAdded:Connect(function(char) --The player character is loaded
        local MAX_DISTANCE = 20

        local radioactiveParts = workspace:WaitForChild("Radiation"):GetChildren()
        while rs.Stepped:Wait() do
        local function GetClosestPart(position: Vector3): BasePart?
            local currentDist = MAX_DISTANCE
            local closestPart = nil
            for _,part in radioactiveParts do
                local distance = (position-part.Position).Magnitude
                if distance <= MAX_DISTANCE then
                    currentDist = distance
                        closestPart = part
                        print("is inside")
    

                end
            end
            return closestPart
        end

            local part = GetClosestPart(char.HumanoidRootPart.Position)
            end
    end)
end)``` I upgraded the script a little bit and now its a bit clearer to see whats going on,  but Can I do something with closest part? so other parts can no longer be detected until the player leaves the part he is in?
local rs = game:GetService("RunService")
local MAX_DISTANCE = 20
local radioactiveParts = workspace:WaitForChild("Radiation"):GetChildren()

local function GetClosestPart(position: Vector3): BasePart?
	local min = math.huge
	local closestPart
	for i = 1,#radioactiveParts do
		local magnitude = (position - radioactiveParts[i].Position).Magnitude
		if magnitude < MAX_DISTANCE then
			if magnitude < min then
				min = magnitude
				closestPart = radioactiveParts[i]
			end
		end
	end
	return closestPart,min
end



game.Players.PlayerAdded:Connect(function(player)--The player that joined
	player.CharacterAdded:Connect(function(char) --The player character is loaded
		rs.Stepped:Connect(function()
			local part,min = GetClosestPart(char.HumanoidRootPart.Position)
			if part then
				print('Part nearby')
				print(min)
				--Code here
			else
				print('No parts nearby')
			end
		end)
	end)
end)
1 Like
-- LocalScript in StarterCharacterScripts

local character = script.Parent
local camera = workspace.CurrentCamera

camera:GetPropertyChangedSignal("Focus"):Connect(function()
	
	local found = false
	
	-- loop all children and if one has a magnitude less then 20 then set found to true
	for i, child in ipairs(workspace.Radiation:GetChildren()) do
		if child.ClassName ~= "Part" then continue end
		if (child.Position - camera.Focus.Position).Magnitude > 20 then continue end
		found = true
		break
	end
	
	if found == true then
		if character.Dosimeter.clicking.Playing == true then return end
		character.Dosimeter.Transparency = 0
		character.Dosimeter.clicking:Play() -- make sure the clicking sound has looped set to true
		print("Radiation Near")
	else
		if character.Dosimeter.clicking.Playing == false then return end
		character.Dosimeter.Transparency = 1
		character.Dosimeter.clicking:Stop()
		print("Radiation Far")
	end

end)
1 Like

You are a legend i love you tysm

Is there a way to make this server wide too? I think sending a remote to the server is making the script unsafe, it should later do damage if the player is inside the area.

Thank you! That works but I have noticed that the current way I try to make it lags the server.

you will need to have a anti exploit that keeps track of the players position to keep it safe

you might not know but a exploiter can teleport the characters position

so using humrp.Position is not safe because a exploiter can set this position to anything they want

so even if you did it on the server side it would still not be safe

in this video i show how to make a module to keep track of the players character position that prevents the player from moving to quickly but it still does not stop a exploiter from writing a script to avoid the radiation automatically I personally would just let the client send a remote event to the server when they get close and another remote event when to walk far away

Well thank you for the hint, I will take a look at the video! :slight_smile:

Then you should use :GetPropertyChangedSignal(‘CFrame’) instead of doing calculations every frame

Whats the difference? I have never heard of focus tbh

Also, what would I write into it? The currentcamera is local only.

You would get the player’s humanoid root part and update distances whenever a change in the position was made, so

player.HumanoidRootPart:GetPropertyChangedSignal('CFrame'):Connect(function()
--Code
end)
1 Like