Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How would I make a weapon hitbox that does constant damage over time?

Alright so I got this tool right? I'm trying to make it so that when its activated if a player/enemy is in a certain distance it'll make them take damage constantly.

I've tried using things like Ontouch and Touched events but they don't seem to be working properly. They kinda just damage them once and never again unless you reactivate the tool.

Heres my current script, it DOES do the damage just not constantly like I need it to

local DebounceTable = {}

script.Parent.Parent:WaitForChild("HITBOX").Touched:Connect(function(objectThatTouchesTheHitbox)
	if objectThatTouchesTheHitbox.Parent then
		if objectThatTouchesTheHitbox.Parent:FindFirstChild("Humanoid") then
			if DebounceTable[objectThatTouchesTheHitbox.Parent] == true then return end
			DebounceTable[objectThatTouchesTheHitbox.Parent] = true
			objectThatTouchesTheHitbox.Parent.Humanoid:TakeDamage(10)
			wait(0.5)
			DebounceTable[objectThatTouchesTheHitbox.Parent] = nil
		end
	end
end)

Some help on this would be much appreciated thankss

2 answers

✓ Accepted answer

You already have half the code, just use your table in an loop Something like:

local DebounceTable = {}

local StartTime = tick()
local HurtTimeTick = 0.0 -- change this to how quick or slow you want it to hurt them
while true do
	local NowTime = tick()
	local DTime = NowTime - StartTime
	if(DTime >= HurtTimeTick) then
		StartTime = tick()
		for Player,_ in pairs(DebounceTable) do
			if(Player ~= nil) then
				Player.Humanoid:TakeDamage(10)
			end
		end
		--print(DTime)
	end
	wait()
end

This is a bit of a hack. But it's a way that would keep track of players/npcs that have contacted the hit box. then your timer in the touch event would remove them after a 0.5 sec delay.

The code in full:

local DebounceTable = {}

script.Parent.Parent:WaitForChild("HITBOX").Touched:Connect(function(objectThatTouchesTheHitbox) 
	local PossibleHuman = objectThatTouchesTheHitbox.Parent
	if objectThatTouchesTheHitbox.Parent then
		if PossibleHuman:FindFirstChild("Humanoid") then
			if DebounceTable[PossibleHuman] == true then return end
			DebounceTable[PossibleHuman] = true
			--PossibleHuman.Humanoid:TakeDamage(10)
			wait(0.5) -- change this to change the duration of pain for the humanoid
			DebounceTable[PossibleHuman] = nil
		end
	end
end)

-- Coment out this bit if you dont want the Touch ended  to fire when the npc/player moves away
script.Parent.Parent:WaitForChild("HITBOX").Touched:Connect(function(objectThatTouchesTheHitbox) 
	local PossibleHuman = objectThatTouchesTheHitbox.Parent
	print(tostring(PossibleHuman).."untouched me!")
	if objectThatTouchesTheHitbox.Parent and  DebounceTable[PossibleHuman] ~= nil then
		DebounceTable[PossibleHuman] = nil
	end
end)

local StartTime = tick() -- start a timer and record our start time

local HurtTimeTick = 0.0 -- change this to speed up the Taken damage the smaller, the faster it will take health away, larger number means slower!

while true do -- main "Pain loop"
	local NowTime = tick()
	local DTime = NowTime - StartTime
	if(DTime >= HurtTimeTick) then
		StartTime = tick()
		for Player,_ in pairs(DebounceTable) do
			if(Player ~= nil) then
				Player.Humanoid:TakeDamage(10)
			end
		end
		--print(DTime)
	end
	wait()
end

Hope this helps! :)

1 comment

0

Ahh alright thanks this helped a ton

Rather than using a hitbox, you could use Magnitude.

local Tool = script.Parent
local Handle = Tool:WaitForChild('Handle')

local Players = game:GetService('Players')

local Dmg = 10 -- damage per rate
local dmgRate = 1 -- how often it damages a player in seconds
local minDistance = 30 -- how close someone has to be in order to be damaged

Tool.Equipped:Connect(function()
	local Player = Players:GetPlayerFromCharacter(Tool.Parent)
	local Character = Player.Character
	if Character then
		local humanoidRootPart = Character:FindFirstChild('HumanoidRootPart')
        if humanoidRootPart then
            while true do
                task.wait(dmgRate)
                for _,player in pairs(Players:GetPlayers()) do
                    if player ~= Player then
                        local pCharacter = player.Character
                        if pCharacter then
                            local pHumanoid, pHumanoidRootPart = pCharacter:FindFirstChild('Humanoid'), pCharacter:FindFirstChild('HumanoidRootPart')
                        if pHumanoid and pHumanoidRootPart then
                            if (pHumanoidRootPart.Position - humanoidRootPart.Position).Magnitude <= minDistance then
                                pHumanoid:TakeDamage(Dmg)
                            end
                        end
                    end
                end
                if Tool.Parent ~= Character then
                    break
                end
            end
        end
	end
end)

This discussion is preserved as it was. New answers, comments, and votes are closed.