So I’m working on making a robust script for detection of players touching a part. The script seems to work fine while the player is touching but not moving but once moving and touching the part it runs too often. I’ve tried a few things but I figure it’s something to do with debouncing when multiple parts touching at the same time.
-- Basic damage part script for continuous damage
local damagePart = script.Parent
local damageRate = 10
local damageCooldown = 1
local isInDamageZone = false -- Start with the player not in the damage zone
local function takeDamage(humanoid)
while isInDamageZone do
humanoid:TakeDamage(damageRate)
wait(damageCooldown)
end
end
damagePart.Touched:Connect(function(otherPart)
local char = otherPart.Parent
local hum = char:FindFirstChild("Humanoid")
local player = game.Players:GetPlayerFromCharacter(char)
if hum and not isInDamageZone then
local touchingParts = damagePart:GetTouchingParts()
for _, part in ipairs(touchingParts) do
if part:IsDescendantOf(char) then
-- Player has entered the damage zone
isInDamageZone = true
takeDamage(hum)
break
end
end
end
end)
damagePart.TouchEnded:Connect(function(otherPart)
local char = otherPart.Parent
local hum = char:FindFirstChild("Humanoid")
if hum then
-- Player has left the damage zone
isInDamageZone = false
end
end)
-- Basic damage part script for continuous damage
local damagePart = script.Parent
--//Controls
local damageRate = 10
local damageCooldown = 1
local damageDebounce = false
--//Tables
local humanoidsTouching = {}
--//Functions
local function takeDamage(humanoid)
while table.find(humanoidsTouching, humanoid) do
humanoid:TakeDamage(damageRate)
task.wait(damageCooldown)
end
end
damagePart.Touched:Connect(function(otherPart)
local char = otherPart.Parent
local hum = char:FindFirstChild("Humanoid")
if not hum or table.find(humanoidsTouching, hum) or damageDebounce then
return
end
damageDebounce = true
table.insert(humanoidsTouching, hum)
takeDamage(hum)
task.wait(damageCooldown)
damageDebounce = false
end)
damagePart.TouchEnded:Connect(function(otherPart)
local char = otherPart.Parent
local hum = char:FindFirstChild("Humanoid")
if not hum then
return
end
local humanoidFound = table.find(humanoidsTouching, hum)
if humanoidFound then
table.remove(humanoidsTouching, humanoidFound)
end
end)
You can just use a while loop to do this (does not need TouchEnded)
local function takeDamage(humanoid)
humanoid:TakeDamage(damageRate)
task.wait(damageCooldown)
end
while true do
wait()
local parts = damagePart:GetTouchingParts()
for i1, otherPart in pairs(parts) do
local char = otherPart.Parent
local hum = char:FindFirstChild("Humanoid")
local player = game.Players:GetPlayerFromCharacter(char)
if player and hum and char then
takedamage(hum)
break
end
end
end
Forgot to check if there are any more parts touching before I removed the humanoid from the table.
Code:
-- Basic damage part script for continuous damage
local damagePart = script.Parent
--//Controls
local damageRate = 10
local damageCooldown = 1
local damageDebounce = false
--//Tables
local humanoidsTouching = {}
--//Functions
local function takeDamage(humanoid)
while table.find(humanoidsTouching, humanoid) do
humanoid:TakeDamage(damageRate)
task.wait(damageCooldown)
end
end
damagePart.Touched:Connect(function(otherPart)
local char = otherPart.Parent
local hum = char:FindFirstChild("Humanoid")
if not hum or table.find(humanoidsTouching, hum) or damageDebounce then
return
end
damageDebounce = true
table.insert(humanoidsTouching, hum)
takeDamage(hum)
task.wait(damageCooldown)
damageDebounce = false
end)
damagePart.TouchEnded:Connect(function(otherPart)
local char = otherPart.Parent
local hum = char:FindFirstChild("Humanoid")
if not hum then
return
end
local humanoidFound = table.find(humanoidsTouching, hum)
if not humanoidFound then
return
end
local partsTouching = damagePart:GetTouchingParts()
for i, part in ipairs(partsTouching) do
if part.Parent == char then
return
end
end
table.remove(humanoidsTouching, humanoidFound)
end)
I used :IsDescendantOf instead of .Parent. This should work.
Code:
-- Basic damage part script for continuous damage
local damagePart = script.Parent
--//Controls
local damageRate = 10
local damageCooldown = 1
local damageDebounce = false
--//Tables
local humanoidsTouching = {}
--//Functions
local function takeDamage(humanoid)
while table.find(humanoidsTouching, humanoid) do
humanoid:TakeDamage(damageRate)
task.wait(damageCooldown)
end
end
damagePart.Touched:Connect(function(otherPart)
local char = otherPart.Parent
local hum = char:FindFirstChild("Humanoid")
if not hum or table.find(humanoidsTouching, hum) or damageDebounce then
return
end
damageDebounce = true
table.insert(humanoidsTouching, hum)
takeDamage(hum)
task.wait(damageCooldown)
damageDebounce = false
end)
damagePart.TouchEnded:Connect(function(otherPart)
local char = otherPart.Parent
local hum = char:FindFirstChild("Humanoid")
if not hum then
return
end
local humanoidFound = table.find(humanoidsTouching, hum)
if not humanoidFound then
return
end
local partsTouching = damagePart:GetTouchingParts()
for i, part in ipairs(partsTouching) do
if part:IsDescendantOf(char) then
return
end
end
table.remove(humanoidsTouching, humanoidFound)
end)
I’m extremely tired right now. The script you wrote starts the damage and it continues when not touching the part. when I retouch the part it stops taking damage. It like toggles between on and off.
Hmm, another approach would be to use a while loop like @neweve2323 did.
Code:
--//Variables
local damagePart = script.Parent
--//Controls
local damageRate = 10
local damageCooldown = 1
--//Tables
local humanoidCache = {}
--//Functions
while task.wait(damageCooldown) do
local touchingParts = damagePart:GetTouchingParts()
for i, part in ipairs(touchingParts) do
local humanoid = part.Parent:FindFirstChildWhichIsA("Humanoid")
if humanoid and not humanoidCache[humanoid] then
humanoidCache[humanoid] = true
humanoid:TakeDamage(damageRate)
end
end
table.clear(humanoidCache)
end
Take a rest then, don’t lose sleep over Roblox lol.