Hello. I have a trap system where if a player clicks a button or presses Ctrl on their keyboard, it places a trap. I noticed that players could spawn multiple traps next to each other, so I added a distance system. But this resulting in sometimes placing down more than 1 trap at a time (Usually 3). Any help would be appreciated!
Local Script:
local color = script.Parent.BackgroundColor3
local imageColor = script.Parent.ImageColor3
local player = game.Players.LocalPlayer
local trapCount = player:WaitForChild('Traps')
local trapText = script.Parent.Parent:WaitForChild('TrapText')
trapText.Text = trapCount.Value
local clicked = false
local inputService = game:GetService('UserInputService')
script.Parent.MouseButton1Click:Connect(function()
if not clicked then
clicked = true
game.ReplicatedStorage.RemoteEvents.TrapEvent:FireServer(player)
script.Parent.BackgroundColor3 = Color3.new(1, 0, 0)
script.Parent.ImageColor3 = Color3.new(1, 1, 1)
wait(3)
script.Parent.BackgroundColor3 = color
script.Parent.ImageColor3 = imageColor
clicked = false
end
end)
game.ReplicatedStorage.RemoteEvents.TrapEvent.OnClientEvent:Connect(function()
script.Parent.Parent.WarnText.Visible = true
wait(3)
script.Parent.Parent.WarnText.Visible = false
end)
inputService.InputBegan:Connect(function(input, gameProcessed)
if not gameProcessed then
if input.UserInputType == Enum.UserInputType.Keyboard then
local keycode = input.KeyCode
if keycode == Enum.KeyCode.LeftControl then
if not clicked then
game.ReplicatedStorage.RemoteEvents.TrapEvent:FireServer(player)
script.Parent.BackgroundColor3 = Color3.new(1, 0, 0)
script.Parent.ImageColor3 = Color3.new(1, 1, 1)
clicked = true
wait(3)
script.Parent.BackgroundColor3 = color
script.Parent.ImageColor3 = imageColor
clicked = false
end
end
end
end
end)
trapCount:GetPropertyChangedSignal('Value'):Connect(function()
trapText.Text = trapCount.Value
end)
Server Script:
local events = game.ReplicatedStorage:WaitForChild('RemoteEvents')
events.TrapEvent.OnServerEvent:Connect(function(player)
local isEnemy = player:FindFirstChild('IsEnemy')
local traps = player:FindFirstChild('Traps')
if isEnemy and isEnemy.Value == true and traps and traps.Value > 0 then
if #game.Workspace.Map.Traps:GetChildren() > 0 then
for _, otherTrap in pairs(game.Workspace.Map.Traps:GetChildren()) do
local distance = (otherTrap.Hitbox.Position - player.Character.HumanoidRootPart.Position).Magnitude
if distance > 7 then
local trap = game.ServerStorage.TrapTypes.Trap:Clone()
for i, v in pairs(trap:GetChildren()) do
if v:IsA('BasePart') then
v.Position = player.Character:FindFirstChild('HumanoidRootPart').Position - Vector3.new(0, 2.4, 0)
end
end
trap.Parent = game.Workspace.Map.Traps
trap.Hitbox.Place:Play()
traps.Value = traps.Value - 1
else
events.TrapEvent:FireClient(player)
end
end
elseif #game.Workspace.Map.Traps:GetChildren() == 0 and isEnemy and isEnemy.Value == true and traps and traps.Value > 0 then
local trap = game.ServerStorage.TrapTypes.Trap:Clone()
for i, v in pairs(trap:GetChildren()) do
if v:IsA('BasePart') then
v.Position = player.Character:FindFirstChild('HumanoidRootPart').Position - Vector3.new(0, 2.4, 0)
end
end
trap.Parent = game.Workspace.Map.Traps
trap.Hitbox.Place:Play()
traps.Value = traps.Value - 1
end
end
end)
It might have something to do with the fact you iterate through every placed trap and place the trap in the for loop itself, meaning that anytime the distance check passes the trap will be placed.
A possible fix would be something like this:
local canPlace = true
for _, otherTrap in pairs(game.Workspace.Map.Traps:GetChildren()) do
local distance = (otherTrap.Hitbox.Position - player.Character.HumanoidRootPart.Position).Magnitude
if distance < 7 then
canPlace = false
end
end
if canPlace then
--place trap
end
local events = game.ReplicatedStorage:WaitForChild('RemoteEvents')
local canPlace = true
events.TrapEvent.OnServerEvent:Connect(function(player)
local isEnemy = player:FindFirstChild('IsEnemy')
local traps = player:FindFirstChild('Traps')
if isEnemy and isEnemy.Value == true and traps and traps.Value > 0 and canPlace then
if #game.Workspace.Map.Traps:GetChildren() > 0 then
for _, otherTrap in pairs(game.Workspace.Map.Traps:GetChildren()) do
local distance = (otherTrap.Hitbox.Position - player.Character.HumanoidRootPart.Position).Magnitude
if distance > 7 then
canPlace = false
local trap = game.ServerStorage.TrapTypes.Trap:Clone()
for i, v in pairs(trap:GetChildren()) do
if v:IsA('BasePart') then
v.Position = player.Character:FindFirstChild('HumanoidRootPart').Position - Vector3.new(0, 2.4, 0)
end
end
trap.Parent = game.Workspace.Map.Traps
trap.Hitbox.Place:Play()
traps.Value = traps.Value - 1
wait(3)
canPlace = true
events.TrapEvent:FireClient(player)
end
end
elseif #game.Workspace.Map.Traps:GetChildren() == 0 and isEnemy and isEnemy.Value == true and traps and traps.Value > 0 and canPlace then
canPlace = false
local trap = game.ServerStorage.TrapTypes.Trap:Clone()
for i, v in pairs(trap:GetChildren()) do
if v:IsA('BasePart') then
v.Position = player.Character:FindFirstChild('HumanoidRootPart').Position - Vector3.new(0, 2.4, 0)
end
end
trap.Parent = game.Workspace.Map.Traps
trap.Hitbox.Place:Play()
traps.Value = traps.Value - 1
wait(3)
canPlace = true
events.TrapEvent:FireClient(player)
end
end
end)
local script
local color = script.Parent.BackgroundColor3
local imageColor = script.Parent.ImageColor3
local player = game.Players.LocalPlayer
local trapCount = player:WaitForChild('Traps')
local trapText = script.Parent.Parent:WaitForChild('TrapText')
trapText.Text = trapCount.Value
local clicked = false
local inputService = game:GetService('UserInputService')
script.Parent.MouseButton1Click:Connect(function()
if #game.Workspace.Map.Traps:GetChildren() > 0 then
for _, otherTrap in pairs(game.Workspace.Map.Traps:GetChildren()) do
local distance = (otherTrap.Hitbox.Position - player.Character.HumanoidRootPart.Position).Magnitude
if distance > 7 and not clicked then
clicked = true
game.ReplicatedStorage.RemoteEvents.TrapEvent:FireServer(player)
script.Parent.BackgroundColor3 = Color3.new(1, 0, 0)
script.Parent.ImageColor3 = Color3.new(1, 1, 1)
game.ReplicatedStorage.RemoteEvents.TrapEvent.OnClientEvent:Wait()
script.Parent.BackgroundColor3 = color
script.Parent.ImageColor3 = imageColor
if trapCount.Value > 0 then
clicked = false
end
elseif distance <= 7 and not clicked then
clicked = true
script.Parent.Parent.WarnText.Visible = true
script.Error:Play()
wait(3)
script.Parent.Parent.WarnText.Visible = false
if trapCount.Value > 0 then
clicked = false
end
end
end
elseif #game.Workspace.Map.Traps:GetChildren() == 0 and not clicked then
clicked = true
game.ReplicatedStorage.RemoteEvents.TrapEvent:FireServer(player)
script.Parent.BackgroundColor3 = Color3.new(1, 0, 0)
script.Parent.ImageColor3 = Color3.new(1, 1, 1)
game.ReplicatedStorage.RemoteEvents.TrapEvent.OnClientEvent:Wait()
script.Parent.BackgroundColor3 = color
script.Parent.ImageColor3 = imageColor
if trapCount.Value > 0 then
clicked = false
end
end
end)
inputService.InputBegan:Connect(function(input, gameProcessed)
if not gameProcessed then
if input.UserInputType == Enum.UserInputType.Keyboard then
local keycode = input.KeyCode
if keycode == Enum.KeyCode.LeftControl then
if #game.Workspace.Map.Traps:GetChildren() > 0 then
for _, otherTrap in pairs(game.Workspace.Map.Traps:GetChildren()) do
local distance = (otherTrap.Hitbox.Position - player.Character.HumanoidRootPart.Position).Magnitude
if distance > 7 and not clicked then
clicked = true
game.ReplicatedStorage.RemoteEvents.TrapEvent:FireServer(player)
script.Parent.BackgroundColor3 = Color3.new(1, 0, 0)
script.Parent.ImageColor3 = Color3.new(1, 1, 1)
game.ReplicatedStorage.RemoteEvents.TrapEvent.OnClientEvent:Wait()
script.Parent.BackgroundColor3 = color
script.Parent.ImageColor3 = imageColor
if trapCount.Value > 0 then
clicked = false
end
elseif distance <= 7 and not clicked then
clicked = true
script.Parent.Parent.WarnText.Visible = true
script.Error:Play()
wait(3)
script.Parent.Parent.WarnText.Visible = false
if trapCount.Value > 0 then
clicked = false
end
end
end
elseif #game.Workspace.Map.Traps:GetChildren() == 0 and not clicked then
clicked = true
game.ReplicatedStorage.RemoteEvents.TrapEvent:FireServer(player)
script.Parent.BackgroundColor3 = Color3.new(1, 0, 0)
script.Parent.ImageColor3 = Color3.new(1, 1, 1)
game.ReplicatedStorage.RemoteEvents.TrapEvent.OnClientEvent:Wait()
script.Parent.BackgroundColor3 = color
script.Parent.ImageColor3 = imageColor
if trapCount.Value > 0 then
clicked = false
end
end
end
end
end
end)
trapCount:GetPropertyChangedSignal('Value'):Connect(function()
trapText.Text = trapCount.Value
end)