NPC Pathfind Closest Player

How can I edit this section of a script so that the NPC chases the closest player to it? There is an annoying isue where it would chase a far player even if there is another one right next to it. Also making sure that the survived value is set to true.

Section of script inside of NPC model:

function chase()
	while true do
		npchumanoid.WalkSpeed = 20
		npchumanoid.JumpPower = 50
		if not walking and not game.Players:GetPlayerFromCharacter(script.Parent) then
			for _, player in pairs(game.Players:GetPlayers()) do
				if player then
					local survivedValue = player:FindFirstChild("survived")
					if survivedValue and survivedValue.Value == true then
						for _, v in pairs(workspace:GetChildren()) do
							if not v:FindFirstChild("Zombie AI") and v:FindFirstChildOfClass("Humanoid") and v:FindFirstChild("Head") then
								if (v:FindFirstChild("Head").Position - npc.Head.Position).magnitude < sight then
									canrandomwalk = false
									local thehumanoid = v:FindFirstChildOfClass("Humanoid")
									local pathfinding = false
									local thehead = v:FindFirstChild("Head")
									while (thehead.Position - npc.Head.Position).magnitude < sight and thehumanoid.Health > 0 and not v:FindFirstChild("Zombie AI") and player do
										npchumanoid.WalkSpeed = 20
										npchumanoid:MoveTo(thehead.Position, thehead)
										local path = game:GetService("PathfindingService"):FindPathAsync(torso.Position, thehead.Position)
										local waypoints = path:GetWaypoints()
										if path.Status == Enum.PathStatus.Success then
											for q, w in pairs(waypoints) do
												if q ~= 1 then
													local allow = 0
													npchumanoid:MoveTo(w.Position, thehead)
													while (torso.Position - w.Position).magnitude > 3.8 and allow < 20 do
														allow = allow + 1
														game:GetService("RunService").Heartbeat:wait()
													end
													if w.Action == Enum.PathWaypointAction.Jump then
														npchumanoid.Jump = true
													end
													if thehumanoid.Health <= 0 then
														break
													end
													if v:FindFirstChild("Zombie AI") then
														break
													end
												end
											end
											for q, w in pairs(npc:GetChildren()) do
												if w.Name == "pospart" then
													w:Destroy()
												end
											end
										else
											npchumanoid:MoveTo(thehead.Position, thehead)
										end
										wait()
									end
									canrandomwalk = true
								else
									canrandomwalk = true
								end
							end
						end
					end
				else
					canrandomwalk = true
				end
			end
		end
		wait()
	end
end

Honestly, this is quite hard to read, but the simplest solution would be to make a function to get the player you want to chase and chase them in each loop. EX:

function chase()
	function getClosestPlayer()
		local closest
		local closestdist
		
		for i,v in pairs(game.Players:GetPlayers()) do 
			if v and v.Character then
				local survived = v:FindFirstChild("survived")
				
				if survived and survived.Value then
					local dist = (v.Character.Head.CFrame.Position -npc.Head.CFrame.Position).Magnitude
					
					if not closest then
						closest = v
						closestdist = dist
					elseif dist < closestdist then
						closest = v
						closestdist = v
					end
				end
			end
		end
		
		return closest
	end
	
	while true do
		npchumanoid.WalkSpeed = 20
		npchumanoid.JumpPower = 50
		
		local target = getClosestPlayer()
		
		local path = game:GetService("PathfindingService"):FindPathAsync(torso.Position, target.Head.Position)
		local waypoints = path:GetWaypoints()
		
		if path.Status == Enum.PathStatus.Success then
			npchumanoid:MoveTo(waypoints[2].Position)
		end
		
		task.wait()
	end
end

This should move to the second waypoint then redo the loop and check for another target, then rinse & repeat. I won’t do the random movement or anything, but you should be able to figure out the rest :slight_smile:

Also, an explanation for the getClosestPlayer function is that it goes through the players, gets the distance between them and the npc, and just gets the one that it closest.

1 Like

I need help putting these two scripts together, some of the lines of the origional script are vital such as making sure the value is true.