Pathfinding problem - Character doesn't follow the waypoints

The video shows the problem
Here is the pathfinding system:

local function moveToDestination(destination)
	local success, message = pcall(function()
		path:ComputeAsync(humanoidRootPart.Position, destination)
	end)

	if (success) and (path.Status == Enum.PathStatus.Success) then
		waypoints = path:GetWaypoints()

		if not reachedConnection then
			reachedConnection = humanoid.MoveToFinished:Connect(function(hasReached)
				if (hasReached) and (nextWaypointIndex < #waypoints) then
					for nextWaypointIndex, waypoint in ipairs(waypoints) do
						humanoid:MoveTo(waypoint.Position)
						if (waypoint.Action == Enum.PathWaypointAction.Jump) then
							humanoid.Jump = true
						end
					end
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
		end
		nextWaypointIndex = 2
		humanoid:MoveTo(waypoints[nextWaypointIndex].Position)

		blockedConnection = path.Blocked:Connect(function(blockIndex)
			if (blockIndex >= nextWaypointIndex) then
				blockedConnection:Disconnect()
				moveToDestination(destination)
			end
		end)
	else
		print("Can't find path")
		warn(message)
	end
end

In my comment in that post, I give a Return Path routine…

Here is all the code in Bot. Uncopylocked.

Hike Ball - Roblox

There are probably more examples in the Library.

Your Script: I can’t tell how you; wait; decide that you have reached the first point, and move on to the next…

In all likelihood, you are just iterating thru all the points, before the NPC even starts to move; and he is just aiming for the last point; right from the start…

1 Like

This loop doesn’t yield and just iterates to the last waypoint, meaning the humanoid will skip all the waypoints inbetween the first and last waypoint.

1 Like

You can avoid this by using Humanoid.MoveToFinished:
Humanoid.MoveToFinished:Wait()

1 Like

Alright! The first problem is solved! I have used your solution and the character has avoid the obstacle. But if I change the destination immediately, the paths are created probably, but the character moves crazily, it does follow the paths but in a crazy way.


Is it a bug or something?

Yes.
None of the code I gave you does that. Which code are you using?

I just added a Wait() in the humanoid.MoveToFinished event:

for nextWaypointIndex, waypoint in ipairs(waypoints) do
			if (nextWaypointIndex <= #waypoints) then
				currentWaypoint = nextWaypointIndex
				humanoid:MoveTo(waypoint.Position)
				if (waypoint.Action == Enum.PathWaypointAction.Jump) then
					humanoid.Jump = true
				end
				humanoid.MoveToFinished:Wait()
			end
		end

Here is the full code that I’m using:

local PathfindingService = game:GetService("PathfindingService")
local path = PathfindingService:CreatePath({
	AgentRadius = 5
})

local mouse = game.Players.LocalPlayer:GetMouse()
local camera = workspace.CurrentCamera
local humanoid = script.Parent:FindFirstChildWhichIsA("Humanoid")
local humanoidRootPart = script.Parent:WaitForChild("HumanoidRootPart")
local UserInputService = game:GetService("UserInputService")
humanoid.WalkSpeed = 25

local MAX_MOUSE_DISTANCE = 200

local blockedConnection
local nextWaypointIndex
local currentWaypoint
local waypoints

local function moveToDestination(destination)
	local success, message = pcall(function()
		path:ComputeAsync(humanoidRootPart.Position, destination)
	end)

	if (success) and (path.Status == Enum.PathStatus.Success) then
		waypoints = path:GetWaypoints()

		for nextWaypointIndex, waypoint in ipairs(waypoints) do
			if (nextWaypointIndex <= #waypoints) then
				currentWaypoint = nextWaypointIndex
				humanoid:MoveTo(waypoint.Position)
				if (waypoint.Action == Enum.PathWaypointAction.Jump) then
					humanoid.Jump = true
				end
				humanoid.MoveToFinished:Wait()
			end
		end

		blockedConnection = path.Blocked:Connect(function(blockedIndex)
			if (blockedConnection >= currentWaypoint) then
				blockedConnection:Disconnect()
				moveToDestination(destination)
			end
		end)
	else
		print("Can't find path")
		warn(message)
	end
end

local function getDestination()
	local mouseLocation = UserInputService:GetMouseLocation()
	local screenToWorldRay = camera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
	local rayDirection = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
	local raycastResult = workspace:Raycast(screenToWorldRay.Origin, rayDirection)
	
	if (raycastResult) then
		moveToDestination(raycastResult.Position)
	else
		print("Can't reach that destination")
	end
end

mouse.Button1Down:Connect(getDestination)

Is it because it didn’t ignore the previous path after creating a new one? So it still moved to the last waypoint of the previous path then moved to the next destination of the second path? Is it right?