Help on NPC Following System

Hello, I am trying to make an NPC following system similar to the roblox game Anime Fighters Simulator where essentially NPCs will always stay at a certain point next to / behind the player, and if the NPC is not at that position, they will move to it. I do not know how to make something like this, I am wondering some tips on how to make this system.

Thank you

2 Likes

I may have an idea but will need to do some testing. I will work on it in the morning and will get back to you when I’ve done some testing.

So they kind of like stay a distance from behind the player?

Kind of, like this:

image

Do you already have a working NPC following system?

Not really, I was trying to use a script to add a part a few studs next to the player and make the NPC’s humanoidrootpart CFrame to the CFrame of that part, then use Motor6D to make that part stay next to the player, but it didn’t seem to be working. The Motor6D made the the part’s position locked to the exact position of the player’s humanoidrootpart and I could not manipulate it at all. So I really do not know how to get past this or any other ways to make this follow system.

1 Like

Try this code out, I tested it and it works perfectly fine.

local PS = game:GetService("Players")
local PTS = game:GetService("PathfindingService")

local owner = "Downrest"
local char = script.Parent
local hrp = char.PrimaryPart
local hum = char:FindFirstChildWhichIsA("Humanoid")

local function GoToPath(target)
	warn("ayyy")
	local path = PTS:CreatePath({
		["AgentRadius"] = 2,
		["AgentHeight"] = 5,
		["AgentCanJump"] = true
	})
	path:ComputeAsync(hrp.Position, target)
	
	if path.Status ~= Enum.PathStatus.Success then
		return
	end

	local waypoints = path:GetWaypoints()

	for _,wp in ipairs(waypoints) do
		local magnitude = (hrp.Position - target).Magnitude
		if magnitude < 7 then
			warn("oops")
			break
		end
		
		hum:MoveTo(wp.Position)
		hum.MoveToFinished:Wait()
	end
end

local function TrackPlayer(name)
	local target = nil
	
	for i,v in ipairs(PS:GetPlayers()) do
		if v.Character and v.Character.Name == name then
			target = v.Character.PrimaryPart
		end
	end
	
	return target
end

while true do
	local target = TrackPlayer(owner)
	
	if target then
		GoToPath(target.Position)
	end
	task.wait(.05)
end

What I did was use PathfindingService, loop through the calculated waypoints of the path, then make the loop stop (practically stopping the humanoid from moving) when it is close enough.

1 Like

Okay, thank you. I will try it out right now

Alright so, it works! There’s a bit of a bug though, while I move the NPC does follow me, but his walk is very buggy. Here is a video of it:

Try this code out:

local PS = game:GetService("Players")
local PTS = game:GetService("PathfindingService")

local owner = "Downrest"
local char = script.Parent
local hrp = char.PrimaryPart
local hum = char:FindFirstChildWhichIsA("Humanoid")

local function SetNetworkOwnership()
	for i,v in ipairs(char:GetDescendants()) do
		if v:IsA("BasePart") then
			v:SetNetworkOwner(nil)
		end
	end
end

local function GoToPath(target)
	warn("ayyy")
	local path = PTS:CreatePath({
		["AgentRadius"] = 2,
		["AgentHeight"] = 5,
		["AgentCanJump"] = true
	})
	path:ComputeAsync(hrp.Position, target)
	
	if path.Status ~= Enum.PathStatus.Success then
		return
	end

	local waypoints = path:GetWaypoints()

	for _,wp in ipairs(waypoints) do
		local magnitude = (hrp.Position - target).Magnitude
		if magnitude < 7 then
			warn("oops")
			break
		end
		
		hum:MoveTo(wp.Position)
		hum.MoveToFinished:Wait()
	end
end

local function TrackPlayer(name)
	local target = nil
	
	for i,v in ipairs(PS:GetPlayers()) do
		if v.Character and v.Character.Name == name then
			target = v.Character.PrimaryPart
		end
	end
	
	return target
end

SetNetworkOwnership()
while true do
	local target = TrackPlayer(owner)
	
	if target then
		GoToPath(target.Position)
	end
	task.wait(.05)
end

When this works, remember to remove the extra warn()s I added. They’re just for testing and it will slow down your game (because it’s going to print every .05 seconds).

Hmm, for some reason it is still doing that same bug. It may be a problem with the NPC I am using, I will double check.