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.
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)
-- 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)
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.
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