NPC's Humanoid.HealthChanged don't work

My npc’s Humanoid.HealthChanged don’t work

if you use that when my npc got damaged it won’t print “hi” :<
myhuman.HealthChanged:Connect(function()
print(“hi”)
end)
code

local Players = game:GetService("Players")
local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")
local lowerTorso = script.Parent:WaitForChild("LowerTorso")
local grab = script.Parent:WaitForChild("Grab")
local grabAnim = myHuman:LoadAnimation(grab)
grabAnim.Priority = Enum.AnimationPriority.Action
local grabSound = head:WaitForChild("Attack")
local screamSound = head:WaitForChild("Scream")
local walk = script.Parent:WaitForChild("Animate").walk.WalkAnim
local clone = script.Parent:Clone()
local anim = myHuman:LoadAnimation(walk)



local alreadygiftedexp = false

local count = 0
local curr = myHuman.Health


function walkRandomly()
	local xRand = math.random(-50,50)
	local zRand = math.random(-50,50)
	local goal = myRoot.Position + Vector3.new(xRand,0,zRand)

	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position, goal)
	local waypoints = path:GetWaypoints()

	if path.Status == Enum.PathStatus.Success then
	else
		--print("Path failed")
		wait(1)
		walkRandomly()
	end
end

function findPath(target)
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position,target.Position)
	local waypoints = path:GetWaypoints()

	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				myHuman.Jump = true
			end
			myHuman:MoveTo(waypoint.Position)
			local timeOut = myHuman.MoveToFinished:Wait(1)
			if not timeOut then
				myHuman.Jump = true
				--print("Path too long!")
				findPath(target)
				break
			end
			if checkSight(target) then
				repeat
					--print("Moving directly to the target")
					myHuman:MoveTo(target.Position)
					attack(target)
					wait(0.1)
					if target == nil then
						break
					elseif target.Parent == nil then
						break
					end
				until checkSight(target) == false or myHuman.Health < 10 or target.Parent.Humanoid.Health < 1
				break
			end
			if (myRoot.Position - waypoints[1].Position).magnitude > 2000 then
				--print("Target has moved, generating new path")
				findPath(target)
				break
			end
		end
	end
end

function checkSight(target)
	local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
	local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
	if hit then
		if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
			--print("I can see the target")
			return true
		end
	end
	return false
end

function findTarget()
	local dist = 50
	local target = nil
	local potentialTargets = {}
	local seeTargets = {}
	for i,v in ipairs(workspace:GetChildren()) do
		local human = v:FindFirstChild("Humanoid")
		local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
		if human and torso and v.Name ~= script.Parent.Name then
			if (myRoot.Position - torso.Position).magnitude < dist and human.Health > 0 then
				table.insert(potentialTargets,torso)
			end
		end
	end
	if #potentialTargets > 0 then
		for i,v in ipairs(potentialTargets) do
			if checkSight(v) then
				table.insert(seeTargets, v)
			elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
				target = v
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	if #seeTargets > 0 then
		dist = 200
		for i,v in ipairs(seeTargets) do
			if (myRoot.Position - v.Position).magnitude < dist then
				target = v
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	if target then
		anim:Play()
	end
	if not target then
		anim:Stop()
	end
	return target 
end

function attack(target)
	if (myRoot.Position - target.Position).magnitude < 6.4 then
		grabAnim:Play()
		grabSound:Play()
		if target.Parent ~= nil then
			local hitbox = target.Parent.Humanoid.Parent:FindFirstChild("hitbox")
			local dr = hitbox:FindFirstChild("dr").Value
			local damage = 10
			if dr < 0 then
				dr = 0
			end
			local percent = dr * 10 
			if percent >= 100 then
				percent = 99
			end
			local moderndamage = damage - percent
			if moderndamage < 0 then
				moderndamage = 0
			end
			target.Parent:FindFirstChild("Humanoid"):TakeDamage(moderndamage)
		end
		wait(0.1)
	end
end

function died()
	local folder = myRoot.Parent.hitbox:FindFirstChild("reward")
	alreadygiftedexp = true
	for i,v in ipairs(folder:GetChildren()) do
		for i,j in ipairs(game.Players:GetChildren()) do
			if j.Name == v.Name and v.Value > (myHuman.MaxHealth / 100) * 45 then
				j.sidesalad.exp.Value = j.sidesalad.exp.Value + 45
				v:Destroy()
			end
		end
	end
	print("Exp Giveaway >:3")
	anim:Stop()
	wait(5)
	clone.Parent = workspace
	game:GetService("Debris"):AddItem(script.Parent,0.1)
end

myHuman.Died:Connect(died)

lowerTorso.Touched:Connect(function(obj)
	if not obj.Parent:FindFirstChild("Humanoid") then
		myHuman.Jump = true
	end
end)

function main()
	local target = findTarget()
	if target then
		myHuman.WalkSpeed = 35
		findPath(target)
	else
		myHuman.WalkSpeed = 8
		walkRandomly()
	end
end

while wait(0.1) do
	if myHuman:GetState() == Enum.HumanoidStateType.Dead then
		if myHuman.Health < 0 and alreadygiftedexp == false then 
		end
		break
	end
	main()
end


myHuman.HealthChanged:Connect(function(damage)
	count = 0
	local folder = myRoot.Parent.hitbox:FindFirstChild("reward")
	local truedamage = curr - damage
	local plr = myRoot.Parent.hitbox:FindFirstChild("plr")
	if myHuman.Health > 0 then
		for i,v in ipairs(folder:GetChildren()) do
			if plr.Value == v.Name then
				v.Value = v.Value + truedamage
				count += 1
				print(v.Name," ",v.Value)
			end
		end
		curr = myHuman.Health
	elseif myHuman.Health < 0 then
		print("why u bullin me i have already ded lol")
	end
	if myHuman.Health > 0 and plr.Value ~= nil and count == 0 then
		local a = Instance.new("IntValue")
		a.Value = truedamage
		a.Name = plr.Value
		a.Parent = myRoot.Parent.hitbox:FindFirstChild("reward")
		plr.Value = nil
		print(a.Name," ",a.Value)
	end
end)

idk how to fix it because it’s not player and i can’t use this


game.Players.PlayerAdded:Connect(function(Player)

	Player.CharacterAppearanceLoaded:Connect(function(Char)
           humanoid.HealthChanged:Connect(function()
           end)
    end)
end)

Are there other ways to solve my problem??

1 Like

You have an unthreaded while loop that’s running before you connect to HealthChanged. While loops will block any subsequent code from executing until it terminates so your HealthChanged connection will never be reached until the while loop ends.

Can be fixed by either wrapping the while loop with task.spawn or moving the while loop below HealthChanged. The latter one is preferable since its just a matter of moving lines of code.

2 Likes

TYSM Really and now all works fine!