Hello, everyone! I’m trying to make a combat system for specific weapons and I found that my weapon, instead of doing 20 damage per hit, deals well over 100+. Any way to stop that?
Hit Function
local function onTouch(partOther)
local humanOther = partOther.Parent:FindFirstChild("Humanoid")
if not humanOther then return end
if humanOther.Parent == Tool then return end
humanOther:TakeDamage(20)
end
and Mouse Clicked function:
Tool.Equipped:Connect(function(Mouse)
Mouse.Button1Down:Connect(function()
if db == false then
db = true
animtrack2:Play()
animtrack2.Stopped:wait()
animtrack:Play()
wait(0.7)
shakeCamera(0.6)
local Connection
Connection = Tool:WaitForChild("Hammer").Touched:Connect(onTouch)
wait()
Connection:Disconnect()
db = false
end
end)
end)
Video showing the bug:
EDIT: Also, it seems kinda delayed which it wasn’t earlier, before I modified the code again
Add a print("Hit") statement in to your onTouch function then test. In the Output window, you will probably see the Hit printing multiple times as the Touch fires repeatedly.
You would need to add a cooldown/debounce to the weapon to stop the Touch repeatedly firing.
Tool.Equipped:Connect(function(Mouse)
Mouse.Button1Down:Connect(function()
if db == false then
db = true
animtrack2:Play()
animtrack2.Stopped:wait()
animtrack:Play()
wait(0.6)
shakeCamera(0.6)
local Connection
if damagedb == false then
Connection = Tool:WaitForChild("Hammer").Touched:Connect(onTouch)
wait()
Connection:Disconnect()
damagedb = true
end
db = false
damagedb = false
end
end)
end)
local Connection
if damagedb == false then
damagedb = true
Connection = Tool:WaitForChild("Hammer").Touched:Connect(onTouch)
wait()
Connection:Disconnect()
end
db = false
damagedb = false
Tool.Equipped:Connect(function(Mouse)
Mouse.Button1Down:Connect(function()
if db == false then
db = true
animtrack2:Play()
animtrack2.Stopped:wait()
animtrack:Play()
wait(0.6)
shakeCamera(0.6)
local Connection
if damagedb == false then
damagedb = true
Connection = Tool:WaitForChild("Hammer").Touched:Connect(onTouch)
wait()
Connection:Disconnect()
end
db = false
damagedb = false
end
end)
end)
You’re using a .Touched event, meaning it could be hitting multiple times, and because of the damage it is dealing, it is applying it over and over again, like @BadDad2004 says;
local function onTouch(partOther)
local humanOther = partOther.Parent:FindFirstChild("Humanoid")
if not humanOther then return end
if humanOther.Parent == Tool then return end
if damagedb then return end
humanOther:TakeDamage(20)
end
You forgot to edit the function, it’s only checking to fire it when its actually used, the touched is still being connected and firing multiple times in a short ammount of time.
The connection you set up that detects touches can fire multiple times; disconnecting it right after connecting it doesn’t guarantee that it’ll fire once. Sometimes it won’t fire at all, because you’re assuming it’ll hit something in the time that you wait before disconnecting it.
What you should be doing is setting up another variable that prevents additional damage from the same attack from being dealt, as well as a separate event listener:
local db = false
local canDmg = true
local hammer = Tool:WaitForChild("Hammer")
Tool.Equipped:Connect(function(Mouse)
Mouse.Button1Down:Connect(function()
if db == false then
db = true
canDmg = true
animtrack2:Play()
animtrack2.Stopped:wait()
animtrack:Play()
wait(0.7)
shakeCamera(0.6)
db = false
canDmg = false
end
end)
end)
hammer.Touched:Connect(function(hit)
if (not canDmg) then return end
canDmg = false
onTouch(hit)
end)
if I probably did something wrong, here’s the full code.
local player = game.Players.LocalPlayer
local Tool = script.Parent --make sure this is a Tool object
local db = false
local blade = Tool:WaitForChild("Damage")
local function shakeCamera(length)
local startTime = tick()
while true do
if tick() - startTime >= length then break end
local x = math.random(-100, 100) / 1000
local y = math.random(-100, 100) / 1000
local z = math.random(-100, 100) / 1000
script.Parent.Parent.Humanoid.CameraOffset = Vector3.new(x, y, z)
workspace.CurrentCamera.CFrame *= CFrame.Angles(x / 100, y / 100, z / 100)
wait()
end
script.Parent.Parent.Humanoid.CameraOffset = Vector3.new(0, 0, 0)
end
local function onTouch(partOther)
local humanOther = partOther.Parent:FindFirstChild("Humanoid")
if not humanOther then return end
if humanOther.Parent == Tool then return end
if canDmg then return end
humanOther:TakeDamage(20)
end
repeat wait(1) until player.Character
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
local animation2 = Instance.new("Animation")
animation2.Name = "Hold"
animation2.Parent = script.Parent
local animation = Instance.new("Animation")
animation.Name = "Slash"
animation.Parent = script.Parent
animation.AnimationId = "http://www.roblox.com/asset/?id=" .. "8425622968"
local animtrack = humanoid:LoadAnimation(animation)
animation2.AnimationId = "http://www.roblox.com/asset/?id=" .. "8425116224"
local animtrack2 = humanoid:LoadAnimation(animation2)
Tool.Equipped:Connect(function(Mouse)
Mouse.Button1Down:Connect(function()
if db == false then
db = true
canDmg = true
animtrack2:Play()
animtrack2.Stopped:wait()
animtrack:Play()
wait(0.7)
shakeCamera(0.6)
db = false
canDmg = false
end
end)
end)
blade.Touched:Connect(function(hit)
if (not canDmg) then return end
canDmg = false
onTouch(hit)
end)
Tool.Unequipped:Connect(function(Mouse)
animtrack:Stop()
animtrack2:Stop()
end)
That’ll prevent the hammer from doing damage when it’s supposed to do damage; change it to this:
if not canDmg then return end
Besides, putting it in the function is redundant, as you already have it here:
blade.Touched:Connect(function(hit)
if (not canDmg) then return end
canDmg = false
onTouch(hit)
end)
You also need to add the canDmg variable to the top of the script so the function can access it:
local player = game.Players.LocalPlayer
local Tool = script.Parent --make sure this is a Tool object
local db = false
local canDmg = true
local blade = Tool:WaitForChild("Damage")
local player = game.Players.LocalPlayer
local Tool = script.Parent --make sure this is a Tool object
local db = false
local canDmg = true
local blade = Tool:WaitForChild("Damage")
local function shakeCamera(length)
local startTime = tick()
while true do
if tick() - startTime >= length then break end
local x = math.random(-100, 100) / 1000
local y = math.random(-100, 100) / 1000
local z = math.random(-100, 100) / 1000
script.Parent.Parent.Humanoid.CameraOffset = Vector3.new(x, y, z)
workspace.CurrentCamera.CFrame *= CFrame.Angles(x / 100, y / 100, z / 100)
wait()
end
script.Parent.Parent.Humanoid.CameraOffset = Vector3.new(0, 0, 0)
end
local function onTouch(partOther)
local humanOther = partOther.Parent:FindFirstChild("Humanoid")
if not humanOther then return end
if humanOther.Parent == Tool then return end
humanOther:TakeDamage(20)
end
repeat wait(1) until player.Character
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
local animation2 = Instance.new("Animation")
animation2.Name = "Hold"
animation2.Parent = script.Parent
local animation = Instance.new("Animation")
animation.Name = "Slash"
animation.Parent = script.Parent
animation.AnimationId = "http://www.roblox.com/asset/?id=" .. "8425622968"
local animtrack = humanoid:LoadAnimation(animation)
animation2.AnimationId = "http://www.roblox.com/asset/?id=" .. "8425116224"
local animtrack2 = humanoid:LoadAnimation(animation2)
Tool.Equipped:Connect(function(Mouse)
Mouse.Button1Down:Connect(function()
if db == false then
db = true
canDmg = true
animtrack2:Play()
animtrack2.Stopped:wait()
animtrack:Play()
wait(0.7)
shakeCamera(0.6)
db = false
canDmg = false
end
end)
end)
blade.Touched:Connect(function(hit)
if (not canDmg) then return end
canDmg = false
onTouch(hit)
end)
Tool.Unequipped:Connect(function()
animtrack:Stop()
animtrack2:Stop()
end)
You also put “Mouse” as a parameter in the Unequipped event listener that was attached to the Tool variable. The Equipped event is the only one of the two that has the Mouse parameter.
Thank you so much, but in order to HIT a target, the “blade” has to be touching the target before the animation, and if the animation plays, my character can’t damage the target