How do you make an npc follow a player?

I’m attempting a different way to make my npc move towards a player.
I’ve already seen youtube tutorials but I’m trying to make it move a different way, but it won’t move.

local Distance = 100
local Titan = script.Parent
local Players = game.Workspace:GetChildren()
local hum = nil
local humroot = nil

function getNearestPlayer(position)
	if Players.FindFirstChild("Model") then
		hum = Players:FindFirstChild("Humanoid")
		humroot = Players:FindFirstChild("HumanoidRootPart")
		if (humroot.Position).magnitude < Distance then
			Titan.Humanoid:MoveTo(humroot, position)
		end
	end
end

while wait() do
	getNearestPlayer()
end

--game.Players.PlayerAdded:Connect(function(player)
	--player.CharacterAdded:Connect(function(character)
		
	--end)
--end)
1 Like
		if (humroot.Position).magnitude < Distance then
			Titan.Humanoid:MoveTo(humroot, position)
		end

You are checking if the magnitude of the Hrp Position is bigger than the distance which is wrong that’s not how it works.
Magnitude is the lenght of a vector (scalar) If you want to check for the distance you would check for the magnitude of(v2-v1) not the hrp position.

Also in your function you passed position but you didn’t in the loop.

Place as a LocalScript in StarterPlayerScripts:

local CollectionService = game:GetService("CollectionService")
local PlayerService     = game:GetService("Players")
local LocalPlayers      = PlayerService.LocalPlayer
local PlayerTag         = "PLAYER"

LocalPlayer.CharacterAdded:Connect(function(character)
  CollectionService:AddTag(character, PlayerTag)
end)

LocalPlayer.CharacterRemoving:Connect(function(character)
  CollectionService:RemoveTag(character, PlayerTag)
end)

Place as a Script in ServerScriptService:

local CollectionService = game:GetService("CollectionService")
local RunService        = game:GetService("RunService")
local PlayerTag         = "PLAYER"

local PriorityQueue = script:WaitForChild("ModuleScript")

local targetCharacter = nil
local TargetPos       = Vector3.new(0, 0, 0) -- probably want to make this the npc's position

RunService.Heartbeat:Connect(function()
  local min  = math.huge
  local char = nil

  for i, character in pairs(CollectionService:GetTagged(PlayerTag)) do
    local d = (character.PrimaryPart.Position - TargetPos).Magnitude

    if d < min then
      min  = d
      char = character
    end
  end

  if targetCharacter ~= char then
    targetCharacter = char
    UpdateNPCTargetPosRemoteEvent:FireClient(
      PlayerService:GetPlayerFromCharacter(char),
      char
    )
  end
end)

2 Likes

This is untested but the general idea of an scratch implementation with the least amount of checks is given here. The outline is:

  1. For every Character that enters the game, tag it for the creation of a table which will be used as a sort of mask to do distance checking on the server side.
  2. On the server side, for every Character instance that’s tagged to be distance checked with the player, check the distance to find the closest player
  3. If the closest player is a new one then send a signal to the npc to update which character it should target.

This is pretty flexible and should work with streaming enabled without a hitch.

That’s pretty much spoon feeding!

i enjoy helping people and don’t really care how i do it

13 Likes
wait(6)
local Distance = 100
local Titan = script.Parent

function getNearestPlayer(Player)
	local hum = Player.Character:WaitForChild("Humanoid")
	local humroot = Player.Character:WaitForChild("HumanoidRootPart")
	if (Titan:WaitForChild("HumanoidRootPart").Position - humroot.Position).Magnitude < Distance then
		Titan:WaitForChild("Humanoid"):MoveTo(humroot.Position)
	end
end

while wait() do
	for _, plr in pairs(game:GetService("Players"):GetPlayers()) do
		getNearestPlayer(plr)
	end
end

Hope it helps!

1 Like