Civillian lags out game and doesnt attack player

I have a script that makes it so if a player punches a npc, the npc will attempt to fight back. Only problem is the npc will lag out the game while trying to punch and does no damage if it does punch.

local Humanoid = script.Parent.Humanoid
function findNearestTorso(pos)
	local list = game.Workspace:children()
	local torso = nil
	local dist = 100
	local temp = nil
	local human = nil
	local temp2 = nil
	for x = 1, #list do
		temp2 = list[x]
		if (temp2.className == "Model") and (temp2 ~= script.Parent) and temp2:FindFirstChild("Reward") == nil then
			temp = temp2:findFirstChild("HumanoidRootPart")
			human = temp2:findFirstChild("Humanoid")
			if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
				if (temp.Position - pos).magnitude < dist then
					torso = temp
					dist = (temp.Position - pos).magnitude
				end
			end
		end
	end
	return torso
end

function hitDamage(humanoid, value)

	humanoid.Health = humanoid.Health - value

end

function animation(humanoid, animation)

	humanoid:LoadAnimation(animation):Play()

end

Humanoid:GetPropertyChangedSignal("Health"):Connect(function()
	local healthChange = Humanoid.Health/Humanoid.MaxHealth
	if Humanoid.Health >= 0 and Humanoid.Health <= Humanoid.MaxHealth then
		script.Parent.Humanoid.WalkSpeed = 10
		while wait(1) do
			local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
			if target ~= nil then
				script.Parent.Humanoid:MoveTo(target.Position, target)
			end
		function hitDamage(humanoid, value)

				humanoid.Health = humanoid.Health - value

			end

			function animation(humanoid, animation)

				humanoid:LoadAnimation(animation):Play()

			end

			script.Parent.HumanoidRootPart.Touched:Connect(function()

				animation(script.Parent.Humanoid, script.Parent.Animation)

				local all = game.Workspace:GetDescendants()

				for i,v in pairs(all) do

					if v.Parent:FindFirstChild("Humanoid") and v.Parent.Name ~= script.Parent.Parent.Name and v.Name == ('HumanoidRootPart') then

						local distance = (script.Parent.Detector.Position).Magnitude

						print(distance)

						if distance < 6 then

							hitDamage(v.Parent.Humanoid, 100)
						end
					end
				end
			end)
		end	
	end
end)

5 Likes

I think it’s supposed to be local list = game.Workspace:GetChildren().

3 Likes

That doesn’t really change anything, but ty for pointing it out.

What’s the detector? local distance = (script.Parent.Detector.Position).Magnitude

1 Like

The detector is the massive part welded onto the npc’s torso. It doesnt have any scripts on it.

You are trying to get the distance from the detector to (0, 0, 0), not the target. This can sometimes end up in some big number.

local distance = (script.Parent.Detector.Position - v.Position).Magnitude

Yeah, I’m fine with that. Im just trying to make it so it doesnt give me the number every milisecond and instead maybe every second.

oh shoot I’m stupid. I just realized what you meant

Realized what you meant. After I put this in the npc kills the player instantly though. Doesnt play animation or anything, just does 100 damage to player. even after I change the damage supposed to be done

I just want to know, why have you defined the hitDamage() and animation() functions twice?

You are damaging the player for almost every object the player has in it’s character model because of local all = game.Workspace:GetDescendants().

I modified your script a bit, sorry if its not your style but it was hard for me to read.

What I change:

  • If statements unnecessary
  • HRP touched inside the loop (?)
  • Functions repeated twice

i think it should work

local Humanoid = script.Parent.Humanoid
local debounce = false

function findNearestTorso(pos)
	local list = game.Workspace:GetChildren()
	local torso = nil
	local dist = 100
	local temp = nil
	local human = nil
	local temp2 = nil

	for x = 1, #list do
		temp2 = list[x]
		if (temp2.ClassName == "Model") and (temp2 ~= script.Parent) and temp2:FindFirstChild("Reward") == nil then
			temp = temp2:findFirstChild("HumanoidRootPart")
			human = temp2:findFirstChild("Humanoid")
			if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
				if (temp.Position - pos).Magnitude < dist then
					torso = temp
					dist = (temp.Position - pos).Magnitude
				end
			end
		end
	end
	return torso
end

function hitDamage(humanoid, value)
	humanoid.Health = humanoid.Health - value
end

Humanoid:GetPropertyChangedSignal("Health"):Connect(function()
	local healthChange = Humanoid.Health/Humanoid.MaxHealth
	if Humanoid.Health >= 0 and Humanoid.Health <= Humanoid.MaxHealth then
		Humanoid.WalkSpeed = 10

		local function animation(humanoid, animation)
			humanoid:LoadAnimation(animation):Play()
		end

		script.Parent.HumanoidRootPart.Touched:Connect(function(v)
			if v.Parent:FindFirstChild("Humanoid") and v.Parent.Name ~= script.Parent.Name then
				if debounce == false then
					debounce = true
					animation(script.Parent.Humanoid, script.Parent.Animation)
					hitDamage(v.Parent.Humanoid, 25) -- (100 = instant kill)

					task.wait(1.8) --cooldown
					debounce = false
				end
			end
		end)

		while task.wait(1) do
			local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)

			if target ~= nil then
				Humanoid:MoveTo(target.Position, target)
			end
		end	
	end
end)
1 Like

Script looks a little funky because it was just two different scripts I made seperatly for other things, then mashed it together for this.

this works perfectly like I needed it to. Sorry about the way the script looked, but ty

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