Touched event is lagging a lot for me

I’m trying to make a damage script with touched event and magnitude, anyway, I already tried to put break (and then it lagged even more) and I even made a debounce but nothing, does anyone have any solution for me? when LightBomb touches me or anything else it causes a lot of lag my fps go to 11

	local db = false
	
	LightBombClone.Touched:Connect(function(hit)
		if not db then
		local ehum = hit.Parent:findFirstChild("Humanoid") or hit.Parent.Parent:findFirstChild("Humanoid")
		if ehum and ehum ~= char then
			for i,v in pairs(game.Workspace:GetDescendants()) do
				local m = (v:IsA("Model") and v) or nil
				if m and m:FindFirstChild("Humanoid") and m:FindFirstChild("HumanoidRootPart") and m ~= char then
					if (LightBombClone.Position - m.HumanoidRootPart.Position).magnitude <= 30 then
						wait(.6)
						db = true
						m.Humanoid:TakeDamage(5)
					end
				end
			end
		end
	else
		wait(5)
		db = false
end
end)

light bomb is a sphere

Most likely to do with use of :GetDescendants as this will filter through the whole of Workspace to find your required asset.

how to fix it then? i dont understand very well

Could you send more of your code? I suspect you’re creating too many connections (you create connections inside a scope that I can’t see, but you dont store a reference to the connection to disconnect it). A connection is an object, so if you don’t call Disconnect on it it will still exist, like a part in the workspace (note this connection will disconnect when the part is destroyed).

Edit:
If you think the magnitude checks are the problem, you can create a new part and use GetTouchingParts() or create a new explosion with a few properties set to 0 and use the Explosion.Hit event. You can also factor out the square root by squaring the 30 and then doing the rest of the pythagorean theorem (you’d need to do the theorem twice).

If the touched event is ran, this causes a lag. Consider debouncing earlier and only add a longer cooldown when it actually hits something. There’s a way where the debounce is valid but the if statements just circuits it off and doesn’t do anything(no stops in the firing).

Why would you use game.Workspace:GetDescendants()? This is the complication.

1 Like

maybe i need use game.Workspace:GetChildren() then?

That doesn’t solve the problem exactly if your workspace happens to be populated with an abundance of objects. Instead, you want to toggle the debounce immediately after checking and then give it a short cooldown regardless if the if statements successfully executed and then toggle it back.

for me the code is doing this, but it is lagging I don’t know how to fix it even now knowing that the problem is the game.Workspace:GetDescendants()

If this is targeting only players, you should utilize Players service and get their characters. Otherwise, if this includes other NPCs, use a folder containing those said NPCs. Then you run GetChildren followed by checking for Humanoid and HumanoidRootPart(or whatever is necessary).

this includes Npcs and Players, is a damage script, and… are you sure the error is this game.Workspace:GetDescendants()?

The implication is that it is not an error, but a sub-optimal method. Try moving all the NPCs into a folder that can be damaged. Then use Players:GetPlayers() followed by Player.Character and Folder:GetChildren().

i think this dont will work the problem is touched event

oh I’m sorry the problem is not the touched event is what you said, still lagging and not damaging the npc now, did I do something wrong?

	local Folder = game.Workspace.Npcs:GetChildren()
	local db = false
	
	LightBombClone.Touched:Connect(function(hit)
		if not db then
		local ehum = hit.Parent:findFirstChild("Humanoid") or hit.Parent.Parent:findFirstChild("Humanoid")
		if ehum and ehum ~= char then
				for i,v in pairs(game.Players:GetPlayers(), Folder, Player.Character) do
				local m = (v:IsA("Model") and v) or nil
				if m and m:FindFirstChild("Humanoid") and m:FindFirstChild("HumanoidRootPart") and m ~= char then
					if (LightBombClone.Position - m.HumanoidRootPart.Position).magnitude <= 30 then
						wait(.6)
						db = true
						m.Humanoid:TakeDamage(5)
					end
				end
			end
		end
	else
		wait(5)
		db = false
end

I believe you aren’t writing this correctly. You will need to write additional lines to create a table, populate it with the players’ characters after they are added in a separate block. The folder, if the NPCs are respawning, use ChildAdded on the function and add each of those into the same table. Then include the table into pairs().

On a second note, it seems extremely redundant to use those lines, it could be skipped.

LightBombClone.Touched:Connect(function(hit)
	if debounce then
		return
	end
	
	debounce = true
	local character = hit.Parent:IsA("Model") and hit.Parent or hit.Parent.Parent
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		if (LightBombClone.Position - character.HumanoidRootPart.Position).Magnitude <= 30 then
			wait(.6)
			debounce = false
			humanoid:TakeDamage(5)
			return
		end
	end
	wait()
	debounce = false
end

image

A typo, just change the capitalized Character to character.

every single time the part is touched, you are looping through every single instance in the workspace. That is that source of your lag. Loop through Players with game.Players:GetPlayers() or tag all humanoids with a tag via CollectionService if you have NPCs.

image

I made another mistake, there’s two extra ends, apparently. Observe how many scopes there are. I edited the script in the previous post, check it.

Is there a other way for you to help me, can you tell me if i can make a touched event wait to fire?