Humanoid.Died() firing 5 times rather then once

Hello Developers!

I’m having trouble with a cutlass weapon, more specifically, it’s cosmetic ability when killing an enemy. Whenever the cutlass gets a kill, it will turn bloody (Which in “Bloody”, I mean a decal of blood plastered on to it) and cause the wielder to say a random line. The only issue is that the Humanoid.Died() keeps firing for 5 times then once. I’ve tried everything to debounces and the hacky

local A
A = Humanoid.Died:Connect(function()
	A:Disconnect()
end)

Command. (Yeah, I know, it was unnecessary, but still.) This is the server-script of the cutlass:

local Cutlass = script.Parent
local ATKEvent = Cutlass:WaitForChild("ATKFireEvent")

local OnKillMessages = {
	"Bloody 'ell! ye've gotten me cutlass all bloody! but that there doesn't matter though, because yer dead.",
	"Told yarr not to mess with me.",
	"Fight like a man next time. Although, yer already dead me mate.",
	"See ye in 'ell!",
	"Me blade ain't a match towards yarr fancy weaponary.",
	"Too fast fer ye? Too bad.",
	"Harharr! Ooooh harharr!",
	"Demoknight, demoknightin? Avast speakin' nonsense, yer not even makin' sense.",
	"Too fast fer yarr bullets?",
	"Maybe if ye where aware that there I can dash, maybe ye would've gotten me!",
	"Harharr! Look at ye! Ye look like a fool to me! Harharr!",
	"I'll see yarr in 'ell, bilge rat. An' ye better clean me blade fer me whenever I spy ye again.",
	"Jolly, yer organs be stuck to me blade. Maybe even yer worthless bones scratched it.. Or maybe even broke it.",
	"Get off me blade, get off, get off!",
	"I should've make me blade not sticky enough fer peasants such as yerself to stick to a more valuable cutlass then yarr.",
	"Picked the wrong person to fight with!",
	"This here isn't gettin' fun anymore, it be too easy fer me now.",
	"Ye know, why even bother fightin' me matey? Like, seriously, why? Ye can't even 'it me in like, five 'its. Maybe I forgotten but I don't give a damn to the depths really. Go take yer weak body somewhere ye can actually win, the graveyard.",
	"I've actually gotten a secret fer ye before I smell yarr stinky breath, the secret ye might ask? I got a god-damn cutlass fer the love o' god!",
	"Try again! IN 'ELL!",
}

ATKEvent.OnServerEvent:Connect(function(Plr,ATKType)
	if ATKType == "LMB" then
		local SwingAnim = Plr.Character.Humanoid:WaitForChild("Animator"):LoadAnimation(Cutlass.Dash)
		SwingAnim:Play()
		task.wait(0.10)
		local CanHit = true
		Cutlass.Handle:FindFirstChild("Swing"):Play()
		Cutlass.Handle.Touched:Connect(function(OnHit)
			local Character = OnHit:FindFirstAncestorWhichIsA("Model")
			local Humanoid = Character and Character:FindFirstChildWhichIsA("Humanoid")
			if Humanoid and CanHit == true then
				CanHit = false
				Cutlass.Handle.Stab:Play()
				Humanoid:TakeDamage(22)
				local Connection
				local function onHumanoidDeath()
					Cutlass.Handle.Blood.Transparency = 0
					game:GetService("Chat"):Chat(Plr.Character.Head,OnKillMessages[math.random(1, #OnKillMessages)],Enum.ChatColor.White)
					Connection:Disconnect()
					
				end
				Connection = Humanoid.Died:Connect(onHumanoidDeath)
			end
		end)
		local LinearVelocity = Instance.new("LinearVelocity",Plr.Character.PrimaryPart)
		local Attachment = Instance.new("Attachment",Plr.Character.PrimaryPart)
		LinearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
		LinearVelocity.PrimaryTangentAxis = Vector3.new(1, 0, 0)
		LinearVelocity.SecondaryTangentAxis = Vector3.new(0, 0, 1)
		LinearVelocity.MaxForce = math.huge
		LinearVelocity.Attachment0 = Attachment
		LinearVelocity.VectorVelocity = Plr.Character.PrimaryPart.CFrame.LookVector * 80
		game:GetService("Debris"):AddItem(LinearVelocity,0.5)
		game:GetService("Debris"):AddItem(Attachment,0.5)
	end
end)
5 Likes

How many times is the attack event being fired? From skimming this, it would appear that every time you fire the event, it will create a new Humanoid.Died, ie: if you hit them seven times, it’ll say it seven times.

A solution to this would be creating a CharacterAdded system that handles deaths individually and just when you attack someone it tags them as you being the attacker.

-- This may not work b/c I wrote this in like 2 minutes w/o testing but it should tho

local players = game:GetService("Players")

local died = function(player)
    print(player,"has died")
    local taggedBy = player.Character:GetAttribute("Tagged")
    if taggedBy ~= nil then
        local killedBy = players:GetPlayerByUserId(taggedBy)
        print(player,"was killed by",killedBy)
    end
end

local onPlayer = function(player)
    local onCharacter = function(character)
       local ended,humanoidDeathEvent  = nil,nil;
       ended = character.AncestryChanged:Connect(function()
           if not character:IsDescendantOf(workspace) then
               ended:Disconnect()
               if humanoidDeathEvent then
                   humanoidDeathEvent:Disconnect()
               end
           end
       end)
       local humanoid = character:WaitForChild("Humanoid")
       humanoidDeathEvent = humanoid.Died:Connect(function()
           died(player)
       end)
    end
    player.CharacterAdded:Connect(onCharacter)
    if player.Character then
       onCharacter(player.Character)
    end
end

players.PlayerAdded:Connect(onPlayer)
for _,plr in pairs(players:GetPlayers()) do
    task.spawn(onPlayer,plr)
end

Place this after Handle.Touched:

Character:SetAttribute("Tagged",Plr.UserId)
1 Like

I’m not entirely sure I understand what’s happening in this script but try replacing
Connection = Humanoid.Died:Connect(onHumanoidDeath)
with
Connection = Humanoid.Died:Once(onHumanoidDeath)

2 Likes

This isn’t needed as any connections signalizing Once will be disconnected immediately after it’s been fired. Automatically. So using a Connection variable is useless and will just use memory.

1 Like

Scrapping what I said before, would this work?
I think the issue is you continue to deal damage to the character even after it has died.

local Character = OnHit:FindFirstAncestorWhichIsA("Model")
local Humanoid = Character and Character:FindFirstChildWhichIsA("Humanoid")
if Humanoid and Humanoid.Health > 0 and CanHit == true then
	CanHit = false
	Cutlass.Handle.Stab:Play()
	Humanoid:TakeDamage(22)
	
	local function onHumanoidDeath()
		Cutlass.Handle.Blood.Transparency = 0
		game:GetService("Chat"):Chat(Plr.Character.Head,OnKillMessages[math.random(1, #OnKillMessages)],Enum.ChatColor.White)
	end
	Humanoid.Died:Once(onHumanoidDeath)
end

@weakroblox35 I didn’t read the script thoroughly enough, my bad.

2 Likes

Apparently not sadly, it still fired multiple times.

Where do I exactly put this line of code at? And where in a script? (Sorry if it’s a bit sloppy, English is my first language, just I don’t know how to put it.)

Is this the only script dealing damage to the humanoid?
If not, can you try commenting some other code that damages the humanoid and see if that changes anything?

Something something is messing around with your heatlh regeneration script, because when player health goes to 0 it’s locked to Dead state unless it goes above 0.

Technically yes, the script actually has two ways of damaging the player via a local script and a remote event. Basically, the local script will tell the remote event what attacks it will do, for example, a dash attack. The remove event then tells the server script (the script which deals the damaging) to execute said attack. Although, one of the attacks being an uppercut is disabled, although if you wish, you can see the local script:

local Cutlass = script.Parent
local Player = game:GetService("Players").LocalPlayer
local ATKEvent = Cutlass:WaitForChild("ATKFireEvent")

local Debounces = {
	LMBCD = false,
	UpperCutCD = false
}
Cutlass.Activated:Connect(function()
	if not Debounces.LMBCD then
		Debounces.LMBCD = true
		ATKEvent:FireServer("LMB")
		task.wait(0.8)
		Debounces.LMBCD = false
	end
end)
Cutlass.Equipped:Connect(function()
	local IdleAnim = Player.Character.Humanoid:WaitForChild("Animator"):LoadAnimation(Cutlass.Idle)
	IdleAnim:Play()
	IdleAnim:AdjustWeight(10)
	Cutlass.Unequipped:Connect(function()
		IdleAnim:Stop()
	end)
end)

--[[
game:GetService("UserInputService").InputBegan:Connect(function(Input,gameProcessedEvent)
	if Input.UserInputType == Enum.UserInputType.Keyboard then
		if Input.KeyCode == Enum.KeyCode.R and not Debounces.UpperCutCD and Enum.HumanoidStateType.Landed then
			Debounces.UpperCutCD = true
			ATKEvent:FireServer("Uppercut")
			task.wait(1.2)
			Debounces.UpperCutCD = false
		end
	end
end)
]]

This is the server-script (Note that it’s updated to have the uppercut script.):

local Cutlass = script.Parent
local ATKEvent = Cutlass:WaitForChild("ATKFireEvent")

local OnKillMessages = {
	"Bloody 'ell! ye've gotten me cutlass all bloody! but that there doesn't matter though, because yer dead.",
	"Told yarr not to mess with me.",
	"Fight like a man next time. Although, yer already dead me mate.",
	"See ye in 'ell!",
	"Me blade ain't a match towards yarr fancy weaponary.",
	"Too fast fer ye? Too bad.",
	"Harharr! Ooooh harharr!",
	"Demoknight, demoknightin? Avast speakin' nonsense, yer not even makin' sense.",
	"Too fast fer yarr bullets?",
	"Maybe if ye where aware that there I can dash, maybe ye would've gotten me!",
	"Harharr! Look at ye! Ye look like a fool to me! Harharr!",
	"I'll see yarr in 'ell, bilge rat. An' ye better clean me blade fer me whenever I spy ye again.",
	"Jolly, yer organs be stuck to me blade. Maybe even yer worthless bones scratched it.. Or maybe even broke it.",
	"Get off me blade, get off, get off!",
	"I should've make me blade not sticky enough fer peasants such as yerself to stick to a more valuable cutlass then yarr.",
	"Picked the wrong person to fight with!",
	"This here isn't gettin' fun anymore, it be too easy fer me now.",
	"Ye know, why even bother fightin' me matey? Like, seriously, why? Ye can't even 'it me in like, five 'its. Maybe I forgotten but I don't give a damn to the depths really. Go take yer weak body somewhere ye can actually win, the graveyard.",
	"I've actually gotten a secret fer ye before I smell yarr stinky breath, the secret ye might ask? I got a god-damn cutlass fer the love o' god!",
	"Try again! IN 'ELL!",
}

ATKEvent.OnServerEvent:Connect(function(Plr,ATKType)
	if ATKType == "LMB" then
		local SwingAnim = Plr.Character.Humanoid:WaitForChild("Animator"):LoadAnimation(Cutlass.Dash)
		SwingAnim:Play()
		task.wait(0.10)
		local CanHit = true
		Cutlass.Handle:FindFirstChild("Swing"):Play()
		Cutlass.Handle.Touched:Connect(function(OnHit)
			local Character = OnHit:FindFirstAncestorWhichIsA("Model")
			local Humanoid = Character and Character:FindFirstChildWhichIsA("Humanoid")
			if Humanoid and Humanoid.Health > 1 and CanHit == true then
				CanHit = false
				Cutlass.Handle.Stab:Play()
				Humanoid:TakeDamage(22)
				local function onHumanoidDeath()
					Cutlass.Handle.Blood.Transparency = 0
					game:GetService("Chat"):Chat(Plr.Character.Head,OnKillMessages[math.random(1, #OnKillMessages)],Enum.ChatColor.White)
				end
				Humanoid.Died:Once(onHumanoidDeath)
			end
		end)
		local LinearVelocity = Instance.new("LinearVelocity",Plr.Character.PrimaryPart)
		local Attachment = Instance.new("Attachment",Plr.Character.PrimaryPart)
		LinearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
		LinearVelocity.PrimaryTangentAxis = Vector3.new(1, 0, 0)
		LinearVelocity.SecondaryTangentAxis = Vector3.new(0, 0, 1)
		LinearVelocity.MaxForce = math.huge
		LinearVelocity.Attachment0 = Attachment
		LinearVelocity.VectorVelocity= Plr.Character.PrimaryPart.CFrame.LookVector * 80
		game:GetService("Debris"):AddItem(LinearVelocity,0.5)
		game:GetService("Debris"):AddItem(Attachment,0.5)
		SwingAnim.Stopped:Wait()
		CanHit = false
	end
	if ATKType == "Uppercut" then
		local UpperCutAnim = Plr.Character.Humanoid:WaitForChild("Animator"):LoadAnimation(Cutlass.Uppercut)
		UpperCutAnim:Play()
		task.wait(0.15)
		local CanHit = true
		Cutlass.Handle:FindFirstChild("Swing"):Play()
		Cutlass.Handle.Touched:Connect(function(OnHit)
			local Character = OnHit:FindFirstAncestorWhichIsA("Model")
			local Humanoid = Character and Character:FindFirstChildWhichIsA("Humanoid")
			if Humanoid and CanHit == true then
				CanHit = false
				Cutlass.Handle.Stab:Play()
				Humanoid:TakeDamage(44)
				local Connection
				local function onHumanoidDeath()
					Cutlass.Handle.Blood.Transparency = 0
					Connection:Disconnect()
				end
				Connection = Humanoid.Died:Connect(onHumanoidDeath)
			end
		end)
		local LinearVelocity = Instance.new("LinearVelocity",Plr.Character.PrimaryPart)
		local Attachment = Instance.new("Attachment",Plr.Character.PrimaryPart)
		LinearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
		LinearVelocity.PrimaryTangentAxis = Vector3.new(1, 0, 0)
		LinearVelocity.SecondaryTangentAxis = Vector3.new(0, 0, 1)
		LinearVelocity.MaxForce = math.huge
		LinearVelocity.Attachment0 = Attachment
		LinearVelocity.VectorVelocity = Vector3.new(0,80,0)
		game:GetService("Debris"):AddItem(LinearVelocity,0.5)
		game:GetService("Debris"):AddItem(Attachment,0.5)
		UpperCutAnim.Stopped:Wait()
		CanHit = false
	end
end)

Wydm “Health Regeneration” script? I don’t got one I scripted by myself, plus, there is already one.

Put this in a separate server script:

local players = game:GetService("Players")

local died = function(player)
    print(player,"has died")
    local taggedBy = player.Character:GetAttribute("Tagged")
    if taggedBy ~= nil then
        local killedBy = players:GetPlayerByUserId(taggedBy)
        print(player,"was killed by",killedBy)
    end
end

local onPlayer = function(player)
    local onCharacter = function(character)
       local ended,humanoidDeathEvent  = nil,nil;
       ended = character.AncestryChanged:Connect(function()
           if not character:IsDescendantOf(workspace) then
               ended:Disconnect()
               if humanoidDeathEvent then
                   humanoidDeathEvent:Disconnect()
               end
           end
       end)
       local humanoid = character:WaitForChild("Humanoid")
       humanoidDeathEvent = humanoid.Died:Connect(function()
           died(player)
       end)
    end
    player.CharacterAdded:Connect(onCharacter)
    if player.Character then
       onCharacter(player.Character)
    end
end

players.PlayerAdded:Connect(onPlayer)
for _,plr in pairs(players:GetPlayers()) do
    task.spawn(onPlayer,plr)
end

Replace the Cutlass code with this:

ocal Cutlass = script.Parent
local ATKEvent = Cutlass:WaitForChild("ATKFireEvent")

local OnKillMessages = {
	"Bloody 'ell! ye've gotten me cutlass all bloody! but that there doesn't matter though, because yer dead.",
	"Told yarr not to mess with me.",
	"Fight like a man next time. Although, yer already dead me mate.",
	"See ye in 'ell!",
	"Me blade ain't a match towards yarr fancy weaponary.",
	"Too fast fer ye? Too bad.",
	"Harharr! Ooooh harharr!",
	"Demoknight, demoknightin? Avast speakin' nonsense, yer not even makin' sense.",
	"Too fast fer yarr bullets?",
	"Maybe if ye where aware that there I can dash, maybe ye would've gotten me!",
	"Harharr! Look at ye! Ye look like a fool to me! Harharr!",
	"I'll see yarr in 'ell, bilge rat. An' ye better clean me blade fer me whenever I spy ye again.",
	"Jolly, yer organs be stuck to me blade. Maybe even yer worthless bones scratched it.. Or maybe even broke it.",
	"Get off me blade, get off, get off!",
	"I should've make me blade not sticky enough fer peasants such as yerself to stick to a more valuable cutlass then yarr.",
	"Picked the wrong person to fight with!",
	"This here isn't gettin' fun anymore, it be too easy fer me now.",
	"Ye know, why even bother fightin' me matey? Like, seriously, why? Ye can't even 'it me in like, five 'its. Maybe I forgotten but I don't give a damn to the depths really. Go take yer weak body somewhere ye can actually win, the graveyard.",
	"I've actually gotten a secret fer ye before I smell yarr stinky breath, the secret ye might ask? I got a god-damn cutlass fer the love o' god!",
	"Try again! IN 'ELL!",
}

ATKEvent.OnServerEvent:Connect(function(Plr,ATKType)
	if ATKType == "LMB" then
		local SwingAnim = Plr.Character.Humanoid:WaitForChild("Animator"):LoadAnimation(Cutlass.Dash)
		SwingAnim:Play()
		task.wait(0.10)
		local CanHit = true
		Cutlass.Handle:FindFirstChild("Swing"):Play()
		Cutlass.Handle.Touched:Connect(function(OnHit)
			local Character = OnHit:FindFirstAncestorWhichIsA("Model")
			local Humanoid = Character and Character:FindFirstChildWhichIsA("Humanoid")
			if Humanoid and CanHit == true then
				CanHit = false
				Cutlass.Handle.Stab:Play()
                                if Humanoid.Health -22 <= 0 and Humanoid.Health >= 1 then
				Humanoid:TakeDamage(22)
                                Character:SetAttribute("Tagged",Plr.UserId)
                                 end
			end
		end)
		local LinearVelocity = Instance.new("LinearVelocity",Plr.Character.PrimaryPart)
		local Attachment = Instance.new("Attachment",Plr.Character.PrimaryPart)
		LinearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
		LinearVelocity.PrimaryTangentAxis = Vector3.new(1, 0, 0)
		LinearVelocity.SecondaryTangentAxis = Vector3.new(0, 0, 1)
		LinearVelocity.MaxForce = math.huge
		LinearVelocity.Attachment0 = Attachment
		LinearVelocity.VectorVelocity = Plr.Character.PrimaryPart.CFrame.LookVector * 80
		game:GetService("Debris"):AddItem(LinearVelocity,0.5)
		game:GetService("Debris"):AddItem(Attachment,0.5)
	end
end)

Alright then! I’ll try the script soon. I’ll let you know if it works or not.

So, a little update, I’ve tested the script and I’ve wondered, does the damage script affect only players, or there are some errors within the script?

Elaborate please, I don’t understand what you’re asking.

Instead, use Humanoid.Died:Once() It creates a connection that only listens for the context once, and automatically disconnects so that you don’t have to initialize a variable or anything. This should work.

Didn’t work sadly, I’ve tried using that before.

:Once()? What about it didn’t work? Maybe you check for the death multiple times in the script?

It still keeps firing multiple times, tried using :Once() once, it didn’t work for some whatever reason.

EDIT: What do you mean “Check for the death too many times”?

Nevermind what I said, please print debug your script really quick. so Everytime you check for the player’s death print something, then tell me how many times it prints and what line