Function executing 4 times

So, as you can see when I kill the dummy, instead of getting 1 point I get 4 of them.
How can I fix this?

function Swing()
	local function AddHitbox(PartWeld, Size)
		local HitboxPart, weld = Instance.new('Part', PartWeld), Instance.new('WeldConstraint', PartWeld)
		HitboxPart.FormFactor = Enum.FormFactor.Custom
		HitboxPart.Size = Size
		
		HitboxPart.CanCollide = false
		HitboxPart.Transparency = 1
		HitboxPart.Name = 'HITBOX_PART'
		HitboxPart.CFrame = PartWeld.CFrame * CFrame.new(0,0,-Size.Z/1.4)
		
		weld.Part0 = HitboxPart
		weld.Part1 = PartWeld
		
		return HitboxPart
	end
	
	
	if BAT_RECOOLING == false then
		if not Character:FindFirstChild('Stunned') then
			BAT_RECOOLING = true

			local BASEBALL_HITBOX_PART = AddHitbox(Character.HumanoidRootPart,
				Vector3.new(
					Character:GetExtentsSize().X + 0.4,
					Character:GetExtentsSize().Y,
					1.7
				)
			)

			BASEBALL_HITBOX_PART.Touched:Connect(function(hit)
				local CHAR = hit.Parent

				if CHAR:FindFirstChildOfClass('Humanoid') then
					if CHAR ~= Character then
						if not CHAR:FindFirstChild('SafeZone') then
							if not BASEBALL_HITBOX_PART:FindFirstChild('USED') then
								local StunAnim = Animations.Stun
								
								local LoadedAnim = CHAR.Humanoid:LoadAnimation(StunAnim)
								local used = Instance.new('BoolValue', BASEBALL_HITBOX_PART)
								local StunnedValue = Instance.new('BoolValue', CHAR)
								
								StunnedValue.Name = 'Stunned'
								used.Name = 'USED'


								local creatorVal = Instance.new('ObjectValue', CHAR)
								creatorVal.Name = 'LastHit'
								creatorVal.Value = Player
								
								CHAR.Humanoid.Died:Connect(function() -- this line
									print(creatorVal.Value.Name.." killed "..CHAR.Name)
									print('yeas')
									Player.leaderstats.Kills.Value += 1
								end)
								
								LoadedAnim:Play()
								CHAR.HumanoidRootPart.Anchored = true
								LoadedAnim.Stopped:Connect(function()
									StunnedValue:Destroy()
									CHAR.HumanoidRootPart.Anchored = false
								end)

								game:GetService('Debris'):AddItem(creatorVal, 0)
								CHAR.Humanoid:TakeDamage(30)

								Bat.Handle.Hit2:Play()
								wait(0.1)
								BASEBALL_HITBOX_PART:Destroy()
							end
						end
					end
				end
			end)

			coroutine.wrap(function()
				if BASEBALL_HITBOX_PART then
					wait(0.1)
					BASEBALL_HITBOX_PART:Destroy()
				end
			end)()

			local SwingAnimation = Humanoid:LoadAnimation(Animations.Smack)
			SwingAnimation:Play()

			Bat.Handle["Sword Swing"]:Play()

			coroutine.wrap(function()
				wait(BAT_RECOOL)
				BAT_RECOOLING = false
			end)()
		end
	end
end

I’d suggest just using a server script in ServerScriptStorage to keep track of all the NPCs and assign points when they die. You’d still use the bats for last hit tagging though.

And if you don’t have all the NPCs in a single folder where you could just simply loop through them, look into CollectionService.

well, the npcs are for testing. the bats will be used for players to fight eachother

Even easier. Using a PlayerAdded event, and a character added event, when the Humanoid dies just check the last hit value and give the player who last hit a point. Also make sure you untag the last hit value after like, 3 seconds a bit hit a character. You don’t want people getting a point from hitting someone and then the player they hit resetting 5 minutes later, lol.

In your tagging script you also want to make sure the LastHit object value doesn’t already exist, if it does just edit the value to the current player. And with writing this, I think I realised why your script is broken. Every time a bat hits an NPC, let’s say 4 times, this bit of codes creates another .Died event on the same humanoid. So when the character finally dies, they all activate.

CHAR.Humanoid.Died:Connect(function() -- this line
	print(creatorVal.Value.Name.." killed "..CHAR.Name)
	print('yeas')
	Player.leaderstats.Kills.Value += 1
end)

Everytime the Baseball bat hits the NPC, you’re connect a new Humanoid.Died event to the NPC. This means that when the NPC eventually dies, every connection made to it will fire.

There’s a couple of different ways you can handle this:

  1. Disconnect the Humanoid.Died connection at the end of the function
  1. Check the Humanoid’s health at the end of the function

This is what each solution would look like:

-- First Solution
local humanoidDied = CHAR.Humanoid.Died:Connect(function()
	print(creatorVal.Value.Name.." killed "..CHAR.Name)
	print('yeas')
    Player.leaderstats.Kills.Value += 1
end)
--...
Bat.Handle.Hit2:Play()
wait(0.1)
BASEBALL_HITBOX_PART:Destroy()
humanoidDied:Disconnect() -- Disconnect the event so that it doesn't fire in the future
-- Second Solution

--...
Bat.Handle.Hit2:Play()
wait(0.1)
BASEBALL_HITBOX_PART:Destroy()

if CHAR.Humanoid.Health < 1 then
   Player.leaderstats.Kills.Value += 1
end

Oh yeah, it also takes 4 hits to kill someone, thats why it was giving me 4 points

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.