Why will it only follow one player and attack one player?

I tested this with two players and it follows a random player, instead of the closest one.

In addition to that, when the player that isn’t being focused on doesn’t take damage.

How do I make it so when the player is in contact with the NPC, it kills them, and follows the player when they are close to the NPC.

Here’s the script:

while wait() do
	local humanoidrootpartpos = {}


function getHumanoid(model)
	for _, h in pairs(model:GetChildren()) do
		if h:IsA("Humanoid") then
			return h
		end
	end
end

local ai = script.Parent
local human = getHumanoid(ai)
local hroot = ai.HumanoidRootPart
local hspeed = hroot.Velocity.magnitude
local pfs = game:GetService("PathfindingService")

function GetPlayerNames()
	local players = game:GetService("Players"):GetChildren()
	local name = nil
	for _, p in pairs(players) do
		if p:IsA("Player") then
			name = tostring(p.Name)
		end
	end
	return name
end


function GetPlayersBodyParts(t)
	local torso = t
	if torso then
		local figure = torso.Parent
		for _, v in pairs(figure:GetChildren()) do
			if v:IsA("Part") then
				return v.Name
			end
		end
	else
		return ("HumanoidRootPart")
	end
end

function GetTorso(part)
	local chars = game.Workspace:GetChildren()
	local torso = nil
	for _, c in pairs(chars) do
		if c:IsA("Model") and c ~= script.Parent and c.Name == GetPlayerNames() then
			local charRoot = c:FindFirstChild("HumanoidRootPart")
			local mag = (charRoot.Position - part).magnitude
			table.insert(humanoidrootpartpos,mag)
			print(humanoidrootpartpos[1])
				torso = charRoot
		end
	end
	return torso
end

for _, aiparts in pairs(ai:GetChildren()) do
	if aiparts:IsA("Part") then
		aiparts.Touched:Connect(function(p)
			if p.Parent.Name == GetPlayerNames() and p.Parent.Name ~= ai.Name then
				local enemy = p.Parent
				local ehuman = getHumanoid(enemy)
ehuman.Health = 0
	
			end
		end)
	end
end

local path
local waypoint
local oldpoints
local isWandering = 0






local enemytorso = GetTorso(hroot.Position)
	if enemytorso ~= nil then -- if player detected
                local TargetMag = math.min(unpack(humanoidrootpartpos))
		if (enemytorso.Position - hroot.Position).magnitude == TargetMag then
		isWandering = 1
		local function checkw(t)
			local ci = 3
			if ci > #t then
				ci = 3
			end
			if t[ci] == nil and ci < #t then
				repeat
					ci = ci + 1
					wait()
				until t[ci] ~= nil
				return Vector3.new(1, 0, 0) + t[ci]
			else
				ci = 3
				return t[ci]
			end
		end
		
		path = pfs:FindPathAsync(hroot.Position, enemytorso.Position)
		waypoint = path:GetWaypoints()
		oldpoints = waypoint
		local connection;
		
		local direct = Vector3.FromNormalId(Enum.NormalId.Front)
		local ncf = hroot.CFrame * CFrame.new(direct)
		direct = ncf.p.unit
		local rootr = Ray.new(hroot.Position, direct)
		local phit, ppos = game.Workspace:FindPartOnRay(rootr, hroot)
		
		if path and waypoint or checkw(waypoint) then
			if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then
				human:MoveTo( checkw(waypoint).Position )
				human.Jump = false
			end
			
		
			
			if connection then
				connection:Disconnect()
			end
			
		else
			for i = 3, #oldpoints do
				human:MoveTo( oldpoints[i].Position )	
			end
		end
end
end
end

I’m not going through your entire code, please only post the parts that are relevant to the problem that you’re trying to solve and which are problematic.

From a quick skim there’s some unrelated and related problems I’ve found. For example, I am not too sure why you’ve wrapped the entire code in a while loop (with wait as a condition no less, which is bad practice). As for whatever function returns the closest item, make sure not to prematurely return and go over all eligible items first before returning the closest: there are some examples in free models regarding how they follow the closest player.

1 Like