NPC Attacks NPCs Instead of Players

I’m trying to make it so that the NPC attacks Players only and not other NPC’s.

For some reason, the NPC’s with this script attack each other instead of attacking the Player, unless you stand close/next to them.

I tried adding LocalPlayer and Player’s Humanoid but that didn’t work.

Script inside NPC: (Follows/Attacks)

local larm = script.Parent:FindFirstChild("HumanoidRootPart")
local rarm = script.Parent:FindFirstChild("HumanoidRootPart")

function findNearestTorso(pos)
	local list = game.Workspace:children()
	local torso = nil
	local dist = 10000
	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) 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




while true do
	wait(1)
	local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
	if target ~= nil then
		script.Parent.Humanoid:MoveTo(target.Position, target)
	end

end

Can anyone please help?

4 Likes

From former experience, I’m certain this was a free-model script?
Anywho, this findNearestTorso function searches through Workspace’s Children and looks for any Humanoids.

To get around this, you should iterate through GetPlayers of the Players service and see if Player:DistanceFromCharacter(pos) returns less than the current dist, if so then set their Character.PrimaryPart to the current torso.

Here’s an example:

local Players = game:GetPlayers("Players");

local function FindNearestTorso(Position)
    local Distance = 10000;
    local Torso = nil;
    
    for _, Player in ipairs(Players:GetPlayers()) do
        if (Player:DistanceFromCharacter(Position) <= Distance) then
            Distance = Player:DistanceFromCharacter(Position);
            Torso = Player.Character.HumanoidRootPart;
        end
    end
end
2 Likes

To identify if it’s a player or not, simply check if that character model has a userId or if it’s a descendant of the playersService

So you would just have to have an additional check

Change this:

if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then

to this:

if (temp ~= nil) and (human ~= nil) and (human.Health > 0) and game.Players:FindFirstChild(Temp2.Name) then
6 Likes

My solution is more simple than others have showed to you:
only need to chamge the name of NPC ’ s Humanoid.

then the npc or zombie should be lookin for Humanoid and not a humanoid named NPC or something else

1 Like

If you’re using this script, please incorporate Returned’s feedback and iterate through the Players service. I have had a nightmarish encounter with NPCs before that used this legacy follow code and even after making it work with only player characters and not NPCs, it was iterating over the entire workspace every second or less. Multiply this by many NPCs and it’s performance hell you do NOT want to sit through.

Like other players’ code have been told, they may not always work, but in case if the NPC has the same name as players in-game, I highly recommend this code below:

if (temp ~= nil) and (human ~= nil) and (human.Health > 0) and game.Players:GetPlayerFromCharacter(Temp2.Name) ~= nil then
-- It is similar to TOP_Crundee123