Attack hits multiple times

I’m making some magic attacks, but I’m having some problems with the damaging. I am currently using this code:

function isInTable(tableValue,toFind)
	local found = false
	for i = 1, #tableValue do
		if tableValue[i] == toFind then
			found = true	
		end
	end
	return found
end

touchConn = clonedExplosion.Touched:Connect(function(hit)
	local hitParent = hit.Parent
	if hit:IsDescendantOf(character) == false and hit.CanCollide == true then
		if hitParent:FindFirstChild("Humanoid") then
			if isInTable(hitCharacters,hitParent) == false then
				table.insert(hitCharacters,hitParent)
				hitParent.Humanoid.Health = hitParent.Humanoid.Health - 25
			end
		end
	end
end)

The attacks are supposed to hit each character one time. I’m using a table to store which characters have been hit by the attack so far, but it seems like touched is triggering a second time before the character has been added to the list, basically making each attack do double the damage it should. I have no idea how to stop this.

1 Like

Prevent multiple hits by the simple practice of a debounce. Basically it checks for a statement on whether it already hit any target before and then ignores the lines before it executes the damage lines.

1 Like

I added a debounce and it didn’t fix the issue. Here is my code after adding it:

if debounce == false then
	debounce = true
	local hitParent = hit.Parent
		if hit:IsDescendantOf(character) == false and hit.CanCollide == true then
			if hitParent:FindFirstChild("Humanoid") then
				if isInTable(hitCharacters,hitParent) == false then
					table.insert(hitCharacters,hitParent)
					hitParent.Humanoid.Health = hitParent.Humanoid.Health - 25
				end
			end
		end
		debounce = false
	end
end)

Did I make a mistake?

Two things:

  1. It’s unique debounces, you’d need a table and a key to reference each target hit. If the key is already referencing to something. Don’t proceed.
  2. Do not turn the debounce back on once hit, if you want a single-strike method. Reset the debounces only if you intend to re-use the attack.

when i damage users, i don’t simply add a debounce, i mostly make damaging parts multiple hit but not on a player (i meant by when a player gets hit, they have an i-frame for a second, but the players that wasn’t affected yet can be damaged), you can try make an if statement if there is a folder named specifically in the hit character then if it finds it, it returns but if it doesn’t it continues then make a folder exactly in the if statement then add a debris to it then damage the user, if ur confused i mean this:

if not chr:findFirstChild("attackcooldown1") then
local db = instance.new("folder", chr)
db.Name = "attackcooldown1"
debris:additem(db, 1)
hum.health = hum.health - 69.420
end

or if you intended the attack to have a maximum hit of 2 you can change the name of what it needs to find instead and if it doesn’t find it, also change exactly the folder instance you created in the chr’s name to the similar things it finds like a debounce, like this

if not chr:findFirstChild("attackcooldown2") then -- i changed the 1 to 2 since it's the 2nd max hit
local db = instance.new("folder", chr)
db.Name = "attackcooldown2" -- i changed the 1 to 2 since it's the 2nd max hit
debris:additem(db, 1)
hum.health = hum.health - 69.420
end

I don’t understand the difference between that and the thing I was doing in the original post.

The original post included one single debounce which is shared between all players and humanoids. Once you hit it, the debounce is toggled. Unique ones requires a table which references all of its hit humanoids, preventing them from being “hit” again.

here is what it means

to counter this, you can write an if statement and see if it finds a specific instance in your character, if it doesn’t, it would then make an instance the same as it tried to find in the if statement then damage the player, in the if statement previously if it found the specific instance in your character, it would do nothing since its purpose is to be on damage cooldown like this

if not chr:findFirstChild("attackcooldown1") then
local db = instance.new("folder", chr)
db.Name = "attackcooldown1"
debris:additem(db, 1)
hum.health = hum.health - 69.420
end

Yes it does. In the first post in this thread, the code that I included adds the characters that are hit by the attack to a table. Before damaging them, it checks if they’re inside of the table, and adds them to the list if they aren’t. If they are in the table, it skips over the damaging step.

1 Like

isn’t that a bit too overcomplicated? otherwise you could use the example i provided.

anyways, there aren’t any code that removes the hit parent from the table making them unable to get damaged again

edit: all u did was just insert it to the table then no code lines that are visible of them being removed from the table after the cooldown time

The problem with yours is that it does something completely different. It temporarily turns off all damage from the explosion.

well, i did say that was an example, you could edit it.

Actually, the Touched event is sometimes unreliable, it seems to be able to fire twice before being stopped by debounce randomly. Since it’s an area-of-effect attack, you should try at least using raycast and casting towards players in a specific distance from the epicenter.

That’s actually not a bad idea. I’ll do that.

or you could use region3 so it’s more stable and not broken like touched, i’m not too good at detecting players inside a zone using raycast

If you visualize the maximum range of the raycast regardless direction, it would form a sphere. This is typically used for fragmentation grenades which sometimes seems to do more or less damage in one specific distance.

Region3 is a good alternative, but it needs to be combined with a distance check between its epicenter and the target player for good measure.

yeahh i still don’t know how to create a spherical range just by using a raycast, i thought it would just be for detecting if a part is blocking to where it’s trying to cast through and some guns

This part requires some knowledge on CFrame. Certain methods from CFrame and some math allows you to freely direct the ray around the pivot.

Fundaments are found here:

1 Like