NPC targetting is buggy

Woo, another question (hope I’m not spamming at this point!).

Alright. So earlier I asked a question on how best I might be able to make non-laggy NPCs and I was given a bunch of tips like centralized scripts and not iterating through the workspace for players.

So after this, I went ahead and created my own follow logic for my NPCs, but I have a problem that I can’t seem to fix; the NPC will not update its target and continue going after one person, even if someone else is closer to the hostile than the person being chased.

I have no clue how to solve this problem. I tried everything - even removing a break in my script.

local function FindPlayerTarget()
	local NearestTorso = nil
	for index, player in pairs(Players:GetPlayers()) do
		if player.Character ~= nil and player.Character:FindFirstChild("Torso") and player.Character:FindFirstChild("Humanoid") then
			if (player.Character.Torso.Position - Torso.Position).magnitude < SearchRange and player.Character.Humanoid.Health > 0 then
				NearestTorso = player.Character.Torso
			end
		end
	end
	return NearestTorso
end

And this is what calls the function:

spawn(function ()
	while wait(1) do
		local SearchResult = FindPlayerTarget()
		if SearchResult then
			Humanoid:MoveTo(SearchResult.Position, SearchResult)
		end
	end
end)

Whether this is just me making a careless mistake and not being able to find it or there’s something I did wrong, I don’t know at all. help pl0x

Right now you are just checking if a Player is within a range of “SearchRange”, and therefore it will just select the last player who fits that criteria. If two players are within the range, it will just pick the last player regardless of actual proximity. The code below adds a new variable, “Proximity”, which updates as the script goes through the list of all players and will only allow “NearestTorso” to change if the distance between a player and an NPC is lower than the Proximity.

local function FindPlayerTarget()
	local NearestTorso,Proximity = nil,SearchRange
	for index, player in pairs(Players:GetPlayers()) do
		if player.Character ~= nil and player.Character:FindFirstChild("Torso") and player.Character:FindFirstChild("Humanoid") then
			local Distance = (player.Character.Torso.Position - Torso.Position).magnitude
			if Distance < Proximity and player.Character.Humanoid.Health > 0 then
				NearestTorso = player.Character.Torso
				Proximity = Distance
			end
		end
	end
	return NearestTorso
end
1 Like

Ooh, thank you.

Another solution I had in mind was putting Torsos and Distances in corresponding tables, calling math.min(x) on a table that had been passed through unpack(t) and then going from there.

So yeah, in short, it was more that I didn’t think this clearly.