Hey! I’m scripting a javelin for a game, and everything seems to be running smoothly, except for one thing. I tried to make it so that once the javelin part recognizes it’s touching something with a humanoid in it, it will deal damage once and then never again. However, this is not the case; it continues to deal damage when touched, making the game very unbalanced. Here’s the code:
BulletClone.Touched:Connect(function(otherPart)
local deb = false
local hum = otherPart.Parent:FindFirstChild("Humanoid")
if deb == false then
if hum then
print("hit a humanoid")
BulletClone.Parent = hum.Parent
hum.Health = hum.Health - 10
deb = true
end
end
wait(5)
BulletClone:Destroy()
end)
Sorry in case the formatting is messy. I’m probably forgetting something basic. Any help is appreciated!
No problem. Also, as @MrOnlyKemal said, you should place the deb boolean outside of your :Connect() method. And please use task.wait() from the task library instead of wait()!
In this case you would probably benefit more from a blacklist as opposed to a time-based debounce. When we successfully detect a humanoid, we can deal damage to it and also cache (i.e., remember) the instance to prevent acting on it twice:
local blacklist: { [Humanoid]: boolean }= {}; -- use keys instead to hasten lookups
BulletClone.Touched:Connect(function(hit)
local hum = otherPart.Parent:FindFirstChildOfClass'Humanoid';
if blacklist[hum] then return; end -- escape if this humanoid is already blacklisted
blacklist[hum] = true; -- cache the new humanoid immediately
-- handle hit logic
print'hit a humanoid';
hum:TakeDamage(10);
end
The way you’ve implemented BulletClone:Destroy() destroys the bullet five seconds after the first hit, which isn’t very intuitive. You can immediately add the bullet to debris outside of the event so that it has a predetermined lifespan:
local debris = game:GetService'Debris';
debris:AddItem(BulletClone, 5);