Pathfinding not willing to drop down


Trying to make an NPC follow the nearest player, but for some reason it just sits there and refuses to come down? It’ll go up just fine, but I can only get it to go down if I guide it down the ramp.

local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local path = PathfindingService:CreatePath({
	WaypointSpacing = math.huge
})
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local function followPath(destination)
	local success, errorMessage = pcall(function()
		path:ComputeAsync(character.PrimaryPart.Position, destination)
	end)

	if success and path.Status == Enum.PathStatus.Success then
		waypoints = path:GetWaypoints()
		blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
			if blockedWaypointIndex >= nextWaypointIndex then
				blockedConnection:Disconnect()
				followPath(destination)
			end
		end)
		if not reachedConnection then
			reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
				if reached and nextWaypointIndex < #waypoints then
					nextWaypointIndex += 1
					humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
		end
		nextWaypointIndex = 2
		humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
	end
end
wait(5) --Let player spawn
local prevpos = character.PrimaryPart.Position --Jump if stuck
for count = 1, math.huge do --Loop forever so it updates nearest player position, for loop to detect first iteration
	if character.PrimaryPart.Position == prevpos then
		humanoid.Jump = true
	end
	prevpos = character.PrimaryPart.Position
	local chars = {}
	for i, v in pairs(Players:GetPlayers()) do
		if v.Character then
			chars[v.Name]=v:DistanceFromCharacter(character.PrimaryPart.Position)
		end
	end
	local closest = math.huge
	local target
	for i, v in pairs(chars) do
		if v < closest then
			closest = v
			target = Players:FindFirstChild(i)
		end
	end
	if count ~= 1 then
		reachedConnection:Disconnect()
		blockedConnection:Disconnect()
	end
	followPath(target.Character.PrimaryPart.Position)
end

I wish it were as simple as making it just go to the position of the nearest player and jump if stuck, but any remotely complex environment would prevent that approach from working sadly.
Edit: I’m also pretty inexperienced with pathfinding, so I might not understand some things.

Would need to know what kind of behavior you are looking for, but a possible workaround would be to detect if the model is stuck somehow(check to see if position hasnt moved > x studs in y amount of second), then if it is stuck in an area, just wander towards a random direction and try to path again. Then check if it’s still stuck, wander towards a random direction. etc etc

Kind of a janky solution, but assuming you are doing all the roblox pathfinding correctly, this would be one of the only ways to get the NPC down. I am not talented enough to be able to look at this code and know if it will work properly so this is the best help I can offer. If you are confident that the pathing code is correct I would give it a try.

1 Like

Could also make the npc’s walk target the player’s character temporarily when you find out that it is stuck, then turn path finding back on after it moves x amount of studs or for x amount of seconds. Would look better than wandering randomly, but could result it getting even more stuck depending on the scenario.

1 Like

https://developer.roblox.com/en-us/api-reference/function/PathfindingService/CreatePath

You would use this method and provide it a dictionary of ‘agent’ parameters.

1 Like