Pathfinding does not follow the path

I’m trying to do good pathfinding to follow players on a map, but I have a problem, the npc model is trying to walk through walls, even though it theoretically has a path for it to follow

I changed my code so many times, and I looked for some solution in other threads, but I can’t find anything that helps my problem, this is my code:

local character = script.Parent
local humanoid = character.Humanoid
local RunService = game:GetService("RunService")

character.PrimaryPart:SetNetworkOwner(nil)

function GetPath(destination)
	local Pathfinding = game:GetService("PathfindingService")
	
	local PathParams = {
		["AgentCanJump"] = true;
		
	}
	local path = Pathfinding:CreatePath(PathParams)
	
	path:ComputeAsync(character.PrimaryPart.Position, destination.Position)
	
	return path
	
end

local waypoints
local reach
local nextway
local blocked

local function showWaypoints(waypoints) 
	if (#waypoints == 0) then return end

	if (game.Workspace:FindFirstChild("Waypoints"))
	then
		game.Workspace.Waypoints:Destroy()
	end
	local wp = Instance.new("Model")
	wp.Name = "Waypoints"
	wp.Parent = game.Workspace
	for p =1, #waypoints do
		local part = Instance.new("Part")
		part.FormFactor = Enum.FormFactor.Symmetric
		part.CanCollide = false
		part.Size = Vector3.new(1,1,1)
		part.Transparency = 0.5
		part.Material = "Neon"
		part.Position = waypoints[p].Position
		part.Anchored = true
		part.BrickColor = BrickColor.Red()
		part.Parent = wp
	end
end

function Walkto()
	local Target = workspace.Player
	local destination = Target.PrimaryPart
	
	local path = GetPath(destination)
	waypoints = path:GetWaypoints()
	if path and path.Status == Enum.PathStatus.Success then
		showWaypoints(waypoints)
		
		for i,v in pairs(path:GetWaypoints()) do
			if not reach then
				reach = humanoid.MoveToFinished:Connect(function(reached)
					
				end)
			end
			if v.Action == Enum.PathWaypointAction.Jump then
				humanoid.Jump = true
			end
			humanoid:MoveTo(v.Position)
		end	
	end
end

RunService.Stepped:Connect(function()
	Walkto()
end)

and here is a video:

robloxapp-20230719-1516388.wmv (122.5 KB)

any kind of help, I will be willing to read, understand, and most importantly, learn

You’re not waiting for the NPC to move to the next waypoint. Just use humanoid.MoveToFinished:Wait() instead:

function Walkto()
	local Target = workspace.Player
	local destination = Target.PrimaryPart
	
	local path = GetPath(destination)
	waypoints = path:GetWaypoints()
	if path and path.Status == Enum.PathStatus.Success then
		showWaypoints(waypoints)
		
		for i,v in pairs(path:GetWaypoints()) do
			if v.Action == Enum.PathWaypointAction.Jump then
				humanoid.Jump = true
			end
			humanoid:MoveTo(v.Position)
            humanoid.MoveToFinished:Wait() -- wait for npc to reach waypoint
		end	
	end
end

Also instead of runservice, i would prob use just a while true loop with task.wait(0.1) . You don’t need to calculate a new path every single frame and I would recommend doing as much checks before actually making a path. Personally, some optimization tips I would do:

  • The best way to use pathfinding is to actually make as little pathfinding calls as you can. Roblox’s pathfinding is slow and expensive. You don’t want to spam call a path if the target didn’t move.

  • Have a magnitude check → if the target is to far from the npc → do nothing or wander.

  • Save the NPC’s previous position → when the loop runs check if his previous position is within 1 - 2 studs of his current position → if he’s been like this for more then 4 - 5 seconds then its most likely the NPC is stuck → generate a new path

  • I would also save the targets previous position (destination) when we make a path to it → then I would compare the target’s current position with its previous (using magnitude) → if the target moved like 7 studs away from its original location that we made a path to → then calculate a new path

  • We don’t need the NPC to path directly to the target. We just want the NPC to get within its line of sight. What I mean by this is that we can cast a ray (from the NPC to the target) with in a certain distance (lets say 30 studs) → if the ray hits the target → we do not path find and just directly chase the target → otherwise continue pathfinding.

  • This is preference but I honestly prefer to use repeat loop instead of humanoid:MoveToFinished. In my experience MoveToFinish has been unreliable. So I simply switched to a magnitude check → if the NPC is within 1 - 2 studs from the waypoint → then i assume he reached the waypoint and move to the next one.

  • Disable any humanoid states you don’t need!! E.g like you may not need the “swimming or climbing” states. This helps boost performance!

Here an example of a demo pathfinding NPC I made a year ago:

External Media

Notice how the path updates when the target (the green part) moves around 7 studs away from the end waypoint. You’ll also see how the path stops updating when the npc is within line of sight (meaning its directly moving to the target).

All in all, just remember that the dumber your NPC is. The better! You only want to update the path when the target moves or something changes!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.