Punch Damage working incorrectly

Hello,

I created a punch script today and it was running fine until I implemented the damage.

When I punch away from the Dummy, and walk into it, it damages the player.

Thank you

Video showcasing the problem:

Local Code(Focus on the DealDamage event):

local Combo = 0
local LastTick = tick()
local Debounce = false
local ComboDebounce = false

local UserInputService = game:GetService('UserInputService')

function DealDamage(Part,Number)
	local HasTouched = Part.Touched:Wait(0.4)
	
	
	if HasTouched then
		if HasTouched.Parent:FindFirstChild('Humanoid') then
			print('So good')
			 if Combo == 3 then
					game.ReplicatedStorage.GameRemotes.DamageEvent:FireServer(HasTouched.Parent,Number,true,true)
			else
				game.ReplicatedStorage.GameRemotes.DamageEvent:FireServer(HasTouched.Parent,Number,true,false)

				end
			
		end
	else
		
	end
end

function Attack(InputObject)
	if InputObject.UserInputType == Enum.UserInputType.MouseButton1 and ComboDebounce == false and Debounce == false then
		Debounce = true
		
		print(math.abs(math.floor(LastTick - tick())))
		
		if math.abs(math.floor(LastTick - tick())) > 3 then
			Combo = 0
			print('WEAPON | Combo reset as it had been left for 2')
		end
		
		Combo = Combo + 1

		if Combo == 1 then
			script.Parent.Events.PlayAnimation:FireServer(script.Parent.Objects['1'])
			DealDamage(game.Players.LocalPlayer.Character.RightHand,10)
			
		else if Combo == 2 then
				print('2')
			script.Parent.Events.PlayAnimation:FireServer(script.Parent.Objects['2'])
				DealDamage(game.Players.LocalPlayer.Character.LeftHand,10)

			else
				print('3')
				script.Parent.Events.PlayAnimation:FireServer(script.Parent.Objects['3'])
				DealDamage(game.Players.LocalPlayer.Character.HumanoidRootPart,20)

				ComboDebounce = true
				wait(1)
				ComboDebounce = false
				Combo = 0
				
			end
			
		end
		LastTick =  tick()	

		wait(0.4)
		Debounce = false
		
	end
end


UserInputService.InputBegan:Connect(Attack)

1 Like

Your code is a bit hard to read, have you tried like “disconnecting” the damage function after a period time of tick()?

I agree, also, there is no need for that else if you have no code to put inside it.

This is a strange way to go about this.

Why are you waiting for the touched event? Are you trying to make a damage cooldown? cause I can see you already have a debounce.

Also on line 56 and 65 you should use task.wait(#) instead of wait(#)

I know this is off topic, but why would you use task.wait vs wait? I’ve never really understood it.

1 Like

task.wait() is generally faster, not by much but it’s good practice to use it

1 Like

Alright thanks, and it doesn’t change how the wait works?

1 Like

Still works the same from what I know. Maybe it works different with threading different scripts, I wouldn’t know, I haven’t tested with threading that much.

1 Like

I already answered and I was going to wait for a response but I figured I’d be more thorough with my original response.

First I have some questions:
Do you want to have it damage someone once every time we swing? Or maybe once every nth second during the swing??

Do you know how animations replicate? If you were to put this script in StarterCharacterScripts and put animations in it, you could just load the animations from the local script and they’ll show up for other people. No need to have a remote event for playing the animations.
image

-- Note: You should now load animations from the Humanoid's "Animator" child.
local hitAnim1 = hum:LoadAnimation(script:WaitForChild("Hit1"))
local hitAnim2 = hum:LoadAnimation(script:WaitForChild("Hit2"))
local hitAnim3 = hum:LoadAnimation(script:WaitForChild("Hit3"))

And one more question, do you know about += and -= ? I know some people do but they just don’t prefer it, but if you don’t:

combo += 1 -- does the same thing as
combo = combo + 1

Next, if I’m understanding what you want to do, you should always listen for the Touched event, not wait for it. Then when the event does happen you can add a debounce so it doesn’t damage the hit character really fast. This code should damage the player once every time we play the animation:

Nerd stuff
local hitChars = {} -- Keep track of who you've hit
function animStopped() -- When any of the animations end we need to reset the list
	table.clear(hitChars)
end
hitAnim1.Stopped:Connect(animStopped)
hitAnim2.Stopped:Connect(animStopped)
hitAnim3.Stopped:Connect(animStopped)

rHand.Touched:Connect(function(hitPart)
	if hitAnim1.IsPlaying or hitAnim2.IsPlaying or hitAnim3.IsPlaying then -- If any of the animations are playing then we're allowed to try to damage the hit character
		if hitPart.Parent:FindFirstChild("Humanoid") and hitPart.Parent ~= char then -- If the hit character is a person and isn't the person swinging then keep going
			if not table.find(hitChars,hitPart.Parent) then -- If the list says we haven't hit this person yet
				table.insert(hitChars,hitPart.Parent) -- Update it to say we have hit them now
				print('So good')
				if Combo == 3 then
					game.ReplicatedStorage.GameRemotes.DamageEvent:FireServer(hitPart.Parent,Number,true,false)	
				else
					game.ReplicatedStorage.GameRemotes.DamageEvent:FireServer(hitPart.Parent,Number,true,false)
				end
			end
		end
	end
end)

An alternative to the table is to have the touched event on the other person’s side, but this wouldn’t work well for damaging NPCs cause you’d have to have a script to receive the damage inside every NPC.
As always, read through the code and see if you can digest it all, don’t just copy and paste. If you have any questions feel free to ask!

1 Like

Hello,

Sorry for the long wait in terms of a response.

I apolgize if my code was hard to read and/or messy. I see what youve done there and ill try it now.

Thanks :slight_smile:

1 Like

With a few modifications this works perfectly.

Thanks!

1 Like

Happy to help! Oh and I forgot to mention but

math.abs(math.floor(LastTick - tick())) -- is the same as
math.floor(tick()-LastTick) -- since tick never goes down

And idk if it was the intent but flooring it means you’d have to wait until 4 seconds have passed in this line

if math.abs(math.floor(LastTick - tick())) > 3 then
	Combo = 0
	print('WEAPON | Combo reset as it had been left for 2')
end

Instead just do something like

if tick()-LastTick >= 2 then
	Combo = 0
	print('WEAPON | Combo reset as it had been left for 2')
end
1 Like