I’ve acctually done something quite similar for a game before, the script below will follow the closest player until a certain distance away and always face the player. The script should be placed inside a model of an NPC that has a Humanoid and a HumanoidRootPart inside.
local npc = script.Parent
local humanoid = npc:WaitForChild("Humanoid")
local rootPart = npc:WaitForChild("HumanoidRootPart")
local runService = game:GetService("RunService")
local players = game:GetService("Players")
local followDistance = 5 --how close npc should get
local moveSpeed = 8 --walking speed
humanoid.WalkSpeed = moveSpeed
local function getClosestPlayer()
local closestPlayer, closestDist
for _, player in pairs(players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local dist = (player.Character.HumanoidRootPart.Position - rootPart.Position).Magnitude
if not closestDist or dist < closestDist then
closestDist = dist
closestPlayer = player
end
end
end
return closestPlayer
end
runService.Heartbeat:Connect(function()
local targetPlayer = getClosestPlayer()
if targetPlayer and targetPlayer.Character and targetPlayer.Character:FindFirstChild("HumanoidRootPart") then
local targetPos = targetPlayer.Character.HumanoidRootPart.Position
local dist = (targetPos - rootPart.Position).Magnitude
--face player
local lookAtCFrame = CFrame.lookAt(rootPart.Position, Vector3.new(targetPos.X, rootPart.Position.Y, targetPos.Z))
rootPart.CFrame = lookAtCFrame
--only walk if too far away
if dist > followDistance then
humanoid:MoveTo(targetPos)
else
humanoid:MoveTo(rootPart.Position) --stop moving
end
end
end)