Weird Issue with hitbox cooldown

	local hits = {}
	local function purpleGetInfo()
		while purple do
			task.wait(0.01)
			local purplePosition = purple.Inner.Position
			for i, hit in pairs(workspace:GetPartBoundsInRadius(purplePosition, 5)) do
				if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Name ~= player.Name then
					if not hit.Parent.Humanoid:FindFirstChild(player.Name) then
						if hits[hit.Parent.Name] then
							return
						end
						hits[hit.Parent.Name] = true
						hit.Parent:FindFirstChild("Humanoid"):TakeDamage(250)
						wait(10)
						hits[hit.Parent.Name] = false
					end
				end
			end
		end
	end
	
	task.spawn(purpleGetInfo)

Can anyone tell me how to solve this issue please? Thanks in advance

1 Like

How does your NPC respawn? If the old NPC doesn’t become the new NPC (like if you just spawn in a new NPC or something), hit might’ve been deleted before that code finished running.

Just temporarily store hit.Parent.Name as a string and reference that instead.

1 Like

Even with actual players

When actual players are respawned, a new body is created and the old one is deleted. Thus, hit would be deleted before that 10 seconds pass.

Although I suppose it wouldn’t really make sense, as things are supposed to stay if you keep a reference to them, but idk, maybe it doesn’t work this way if they’re garbage collected or something.

1 Like

So what should I do? Make hit shorter?

No, store hit.Parent.Name as a string and do hits[(name of the string)] instead

(considering that this is only meant to be a cooldown anyways, and hit.Parent.Name obviously shouldn’t be changing)

1 Like

I kinda tried doing what u said but this is where I got

	local hits = {}
	local function purpleGetInfo()
		while purple do
			task.wait(0.01)
			local purplePosition = purple.Inner.Position
			for i, hit in pairs(workspace:GetPartBoundsInRadius(purplePosition, 10)) do
				if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Name ~= player.Name then
					if not hit.Parent.Humanoid:FindFirstChild(player.Name) then
						for i, v in hits do
							if v == hit.Parent.Name then
									return
								end
						end
						hit.Parent:FindFirstChild("Humanoid"):TakeDamage(250)
						table.insert(hits, hit.Parent.Name)
						local function removeFromHits()
							task.wait(2)
							table.remove(hit.Parent.Name)
						end
						task.spawn(removeFromHits)
					end
				end
			end
		end
	end
	
	task.spawn(purpleGetInfo)

ServerScriptService.Hollow Purple Server:256: invalid argument #1 to 'remove' (table expected, got string)

I don’t think thats what I meant lol (im not sure, I can’t really tell whats happening in that script tbh)

this is what I meant (I marked the things I changed with comments btw)

local hits = {}
	local function purpleGetInfo()
		while purple do
			task.wait(0.01)
			local purplePosition = purple.Inner.Position
			for i, hit in pairs(workspace:GetPartBoundsInRadius(purplePosition, 5)) do
				if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Name ~= player.Name then
					if not hit.Parent.Humanoid:FindFirstChild(player.Name) then
						if hits[hit.Parent.Name] then
							return
						end
						hits[hit.Parent.Name] = true
						local temp = hit.Parent.Name --added line
						hit.Parent:FindFirstChild("Humanoid"):TakeDamage(250)
						wait(10)
						hits[temp] = false --changed line
					end
				end
			end
		end
	end
	
	task.spawn(purpleGetInfo)
1 Like

Now if I have multiple dummies with different names only one takes damage but the rest dont

Yea, but isn’t this code supposed to not hit other dummies until the wait is over?

Otherwise, your original wouldn’t hit the other dummies either. You’re wait(10)ing the for loop for the GetPartBoundsInRadius, which means that the next part that will be checked will be checked 10 seconds later.

If you want this to be able to hit everything without a 10 second cooldown (which tbh I assumed you intended for there to be a 10 second cooldown), you would want to instead spawn a seperate thread which runs the function that adds the hit part to the table and then later removes it later on (so it doesn’t interfere with your main function).

I don’t really know how to use task.spawn (and I sadly don’t have enough time to learn right now, considering I have to go in less than an hour), but I will provide a pseudocode thingie below

local hits = {}
	local function purpleGetInfo()
		while purple do
			task.wait(0.01)
			local purplePosition = purple.Inner.Position
			for i, hit in pairs(workspace:GetPartBoundsInRadius(purplePosition, 5)) do
				if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Name ~= player.Name then
					if not hit.Parent.Humanoid:FindFirstChild(player.Name) then
						if hits[hit.Parent.Name] then
							return
						end
						spawn a seperate thread which runs the following code:
							hits[hit.Parent.Name] = true
							local temp = hit.Parent.Name
							hit.Parent:FindFirstChild("Humanoid"):TakeDamage(250)
							wait(10)
							hits[temp] = false
					end
				end
			end
		end
	end
	
	task.spawn(purpleGetInfo)

Also, for your convenience, heres a post which seems to cover the basics of how to use task.spawn and coroutine: Can I run a function without stopping my main function?

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.