Pathfinding bug

soo I encountered into another pathfinding bug (roblox nice job team) and I don’t really know any solutions for it.

how to reproduce:
spawn some troops on both sides and wait for a while, it will bug out and troops will move like both of their legs are disabled

related script:

function spawner(func,...)
	local co = coroutine.wrap(func)
	co(...)
end

function infantryToTarget(unit)
	local path = game:GetService("PathfindingService"):CreatePath()

	local success, errorMessage = pcall(function()
		path:ComputeAsync(unit.root.Position, unit.target.Position)
	end)

	local waypoints

	local waypointIndex = 2

	local reachedConnection
	local blockedConnection

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

		unit.human:MoveTo(waypoints[waypointIndex].Position)

		blockedConnection = path.Blocked:Connect(function(blockedIndex)
			if blockedIndex >= waypointIndex then
				blockedConnection:Disconnect()
				infantryToTarget(unit)
			end
		end)

		if not reachedConnection then
			reachedConnection = unit.human.MoveToFinished:Connect(function(reached)
				if unit.target then
					if reached and waypointIndex < #waypoints then
						waypointIndex += 1
					else
						reachedConnection:Disconnect()
						blockedConnection:Disconnect()
					end
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
		end
	else
		reachedConnection:Disconnect()
		blockedConnection:Disconnect()
	end
end

spawner(function()
	while task.wait() do
		updateTarget()
	end
end)

function infantryHandler(unit)
	while task.wait() do
		if unit and unit.target and unit.class == "Infantry" then
			infantryToTarget(unit)
		end
	end
end

here’s video

It looks like rather than pathfinding being broken, you are simply not using the PathfindingService correctly. I have looked through your code and have found a couple points of improvement for you:

  1. By the looks of it you are looping through each unit and for each unit in every loop you are generating a new path rather than re-using previously created paths. Pathfinding algorithms are generally expensive to run (not something Roblox can change. It’s simply how the math works). Constantly generating new paths can slow down your code a lot, especially when you are trying to control many units at once. Instead, it is worth grouping your units together into a ‘squad’ and generating just one path for the whole squad together, which the units will be sharing.

  2. When a path is generated it will contain a list of waypoints. You are correctly using Humanoid:MoveTo() to move your units to the first ‘node’ in the list of waypoints. And once the humanoid finishes moving you are also correctly increasing the waypointIndex variable. However, you are forgetting to call Humanoid:MoveTo() again to move your unit to the next waypoint. The first waypoint on the path will be very close to the unit’s original location. So when you tell the unit to move, it will take a step to move to the next waypoint and then stop as it has reached the waypoint and is not given any further instructions to move to the next waypoint. This is why it looks like the units are ‘bugging out’; they are in fact done moving towards their instructed location.

I would suggest looking up a tutorial on how Roblox pathfinding works with example code to base your own code on. Pathfinding can be tricky to get right especially when working with multiple NPCs. Once you have a solid foundation, I would also recommend looking into ‘flocking behavior’ (you can Google that term and find some good resources) to make your units walk together into a group without having them walk over each other.

3 Likes

Can you provide an example or reference on generating one path for multiple NPCs? (as opposed to every npc generating their own path which is expensive)

I experienced this issue. Change all the model’s serverowner to nil!!

local function serverOwnCharacter(character)
	for _, Prts in character:GetDescendants() do

		if not Prts:IsA("BasePart") then continue end
		Prts:SetNetworkOwner(nil)

	end
end

This was off of my pathfinding script but just run this for each AI and it won’t lag like that. My AI script can handle around 200 and some change without any weird issues. Though They do have weird behaviors when you are pretty far away and that’s just normal for games overall.

Just realized this post is from 2023, my bad for bumping this post.