NPCs keep running into each other

If your AgentRadius parameter is too big, then it won’t be able to find a valid path between places because even if there’s enough space, the NPC thinks it doesn’t have enough space because of the AgentRadius, which is the minimum width of the path. If you clean your code up a bit, it should make it easier to see why it stops on the return path.

Also, please specify: when you say the NPC stopped on the return path, does it give you the warning that it could not find a path? If so, there’s probably too many NPCs in the way and you need to make the NPC try again if it can’t find a path. If not, the only thing I can say for now is make sure that your returnDestination is referencing the correct object back at where the NPC is supposed to go.

No warning, and the returnDestination is right where the NPC started. I made sure it was anchored and CanCollide was false, and both were already set to that.

Try putting debug messages in followPathReturn() and have it print a warning if no path can be found.

I believe that it should print something when the NPC stops on the return path (unless you mean the NPC stops somewhere in the middle of the return path).

If the problem really is that the NPC can’t compute a path when returning then have the NPC try again to compute the path after waiting a little bit.

Ugh!

local PathfindingService = game:GetService("PathfindingService")
 
-- Variables
local deliverer = script.Parent
local humanoid = deliverer.Humanoid
local destination = script.Parent.Parent.CashGiver
local returnDestination = script.Parent.Parent.DeliveryReturn

local isOnReturnPath = false

local box = game.ServerStorage.Box
local newBox = box:Clone()
newBox.Parent = deliverer

local animation = Instance.new("Animation")
animation.AnimationId = "http://www.roblox.com/asset/?id=4837921759"

local animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()
 
-- Loop
-- Variables to store waypoints table and deliverer's current waypoint
local waypoints
local currentWaypointIndex

local path = PathfindingService:CreatePath()

-- Destination functions
 
function followPath(destinationObject)
	-- Compute and check the path
	path:ComputeAsync(deliverer.HumanoidRootPart.Position, destinationObject.PrimaryPart.Position)
	-- Empty waypoints table after each new path computation
	waypoints = {}
 
	if path.Status == Enum.PathStatus.Success then
		-- Get the path waypoints and start deliverer walking
		waypoints = path:GetWaypoints()
		-- Move to first waypoint
		currentWaypointIndex = 1
		humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
		print("Success")
	elseif path.Status == Enum.PathStatus.NoPath then
		-- Error (path not found); stop humanoid
		warn("Path not found, stopping NPC")
		humanoid:MoveTo(deliverer.HumanoidRootPart.Position)
	else
		error("Somehow the script made its way here")
	end
end
 
function onWaypointReached(reached)
	print("Reached: "..reached.."Waypoint Index: "..currentWaypointIndex)
	if reached and currentWaypointIndex < #waypoints then
		currentWaypointIndex = currentWaypointIndex + 1
		humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
	elseif reached and currentWaypointIndex == #waypoints then
		if not isOnReturnPath then
			wait(1)
			isOnReturnPath = true
			followPath(returnDestination)
		elseif isOnReturnPath then
			wait(1)
			isOnReturnPath = false
			followPath(destination)
		end
	end
end
 
function onPathBlocked(blockedWaypointIndex)
	-- Check if the obstacle is further down the path
	if blockedWaypointIndex > currentWaypointIndex then
		-- Call function to re-compute the path
		followPath(destination)
	end
end

--  Return functions

-- Connect 'Blocked' event to the 'onPathBlocked' function
path.Blocked:Connect(onPathBlocked)
 
-- Connect 'MoveToFinished' event to the 'onWaypointReached' function
humanoid.MoveToFinished:Connect(onWaypointReached)
 
followPath(destination)

Now the output says

Success

while the NPC doesn’t move at all anymore! :expressionless: :rage:

To clarify, the NPC not only doesn’t walk on the return path, but the NPC also doesn’t walk on the original path?
And success only prints once, right?

1 Like

When loaded in, the NPC does not do anything, it just walks in place.

I only found Success once and (Doesn’t really matter but) I get spammed Debounce is already true (This is for when it gets cash by touching the first destination)

Are you only moving the Character towards the first waypoint? And is the followPath function only being called once?

I didn’t see anything wrong with your script (although I may have overlooked something so no guarantees), but I thought of several possibilities if the NPC didn’t even reach the first waypoint.

  • Something is anchored in your NPC such as its HumanoidRootPart or the box it’s holding
  • Your NPC’s humanoid object’s speed or something was tampered with
  • Your destination object isn’t where you expected it to be

Oh, and there’s one more thing: although it shouldn’t affect anything, you forgot the local keyword when defining all your functions. In general, avoid global variables and functions as they’re inefficient.

1 Like

Since onWaypointReached() is connected to humanoid.MoveToFinished, it should print the debug message “Reached…” when the NPC reaches the first waypoint and then move the NPC to the next waypoint. It looks like the NPC isn’t reaching the first waypoint.

Actually, I got an error for

saying that reached was a boolean and I was trying to print it as a string (or something)

Sorry, this is turning into a discussion!

There’s nothing to apologize for. The basic premise is still there; you have a problem with pathfinding and we’re trying to help you with it.

So then it looks like the NPC did reach the first waypoint. Before going on, is there anything else we should know or are you only seeing “Success” and “Reached…” in the output? What about after you fixed the boolean error?

If you don’t know how to fix the boolean error, there are a couple ways to solve it.

print("Reached: " .. tostring(reached))
-- or
print("Reached:", reached)

I see this

Success
Error

then a whole other random stuff.

You’re going to have to be a little more specific. As I understand it, you see those two things and nothing else is relevant to the pathfinding issue. The NPC is walking in place and… did it or did it not print “Reached…”? Also, how come it printed “Error” and what does that mean? I don’t see a debug message in your code printing “Error”. Or are you saying that boolean-string-concatenation error is still there and it’s printing that error?

Error was just meant for the error I was talking about (the boolean one). I didn’t exactly remember it.

Aha I found the error!


With this line:

print("Reached: " .. tostring(reached) .. "Waypoint Index: " .. currentWaypointIndex)

It ended up saying true: it reached the waypoint (first pic). Then on the way back (first/second pic) the NPC stopped like it always did and it said false instead of true.

So with this function

local function onWaypointReached(reached)
	print("Reached: " .. tostring(reached) .. " Waypoint Index: " .. currentWaypointIndex)
	if reached and currentWaypointIndex < #waypoints then
		currentWaypointIndex = currentWaypointIndex + 1
		humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
	elseif reached and currentWaypointIndex == #waypoints then
		if not isOnReturnPath then
			wait(1)
			isOnReturnPath = true
			followPath(returnDestination)
		elseif isOnReturnPath then
			wait(1)
			isOnReturnPath = false
			followPath(destination)
		end
	end
end

I need to find somewhere to put if reached is false.

It could have failed to reach the waypoint if the path was blocked, however, if the path was blocked, then it should have computed a new path to the destination, in which case the problem would be automatically handled. But if you didn’t see any errors about not being able to compute a new path and the NPC stopped moving, that means it failed to fire the Blocked event when the NPC couldn’t reach the next waypoint.
Calling followPath() again if the waypoint was not reached could be one thing you could try.

1 Like

Yay I found my solution! When reached was false, I fired the followPath() function again and it worked!

Wait, I still have a problem. Changing the script didn’t help me with my original problem. The NPCs still run into each other…

Using Physics Service is the easist and best way to do that.

How would I do this? Just note that I don’t really want the NPCs to be set to CanCollide = false.