How to avoid AI taking the same path to a target/ crowding

I’ve been having this issue with my AI units for a while now and have tried a few solutions but none seem to work. Basically, my AI uses pathfinding to find a target and move to it, but they’ll crowd around each other if a lot try to move to the same target at the same time. Recently I tried a method which almost worked - I added PathfindingModifiers to welded parts within each AI model that took up the character’s size.

However, I forgot that each AI would try to avoid not only other AIs hitbox part but its own as well, which makes them get stuck walking in circles. Is there any way I could somehow make the AI ignore its own hitbox (besides creating a unique label for each individual AI, since I have too many for this to be a viable solution) and if there isn’t, is there another way I could stop AI crowding?

In case it helps, here’s an outline of the hitbox:
ates

I think you would need to create a label for each one and set the cost in the parameters.

I’ve already set up the labels properly, the issue is the label is the same for each AI and thus it calculates avoiding its own hitbox which makes it get stuck. I can’t create a unique label for each AI as im going to have many of them in my game and I think it’ll cause a lot of lag if I have to check so many different labels for each individual other AI. If there was some blacklist system this wouldn’t be an issue, but there isn’t one to my knowledge.

If one NPC has already calculated a path to a point, can he make a check that another NPC does not calculate a path to the same point?

I’ve thought about that, however -

I do want it to be possible for multiple AI to attack a target at once, I just need them to not get stuck behind each other and such. e.g, two AI pick the same target, and they spread out to attack and kind of “encircle” it, instead of standing behind one another. The AI tends to but not always make a conga line when fighting.

I tested making the hitbox thinner and only directly behind each AI just now. This seems to have the desired effect I stated above, where when multiple AI attack one target, they’ll (usually but not always) spread out and attack from multiple directions. The only flaw is that they still jitter around sometimes which looks a bit odd, but I think I’d rather have that than the crowding around.

However ideally I’d have neither, so hopefully I can find a method where I can make them simply spread out a bit if they’re too close to one another without using PathfindingModifiers, since I can’t think of a solution that uses them and doesn’t jitter.

Not an expert but Im guessing boids could be a potential solution since it offers seperation to avoid crowding:

Seems like a scarce topic within roblox would be good for a community resource.

Other topics without example code but propose the same algorithm

3 Likes

The bit in the second article about a lead zombie using pathfinding and the rest following is something I really should’ve thought of before but somehow didn’t - now that I think about it, the game that I’m basing my own game after might use a similar system I was never aware of (in terms of AI, when they spawn in, there’s an “officer” unit that spawns with accompanying “private” AIs) which I replicated in my own game but with no extra functionality, just to make it look nicer with the formation. However, I could hopefully make a system like that to avoid flocking. Thank you for the information

1 Like

When the NPC sees the target in line of sight (use raycast to check this), you need to use not pathfinding but MoveTo, and then use some formula to keep the NPCs at a certain distance from each other. This is not a ready-made solution, but just an idea how to do it.

local Workspace = game:GetService("Workspace")
local NPCs = Workspace.NPCs 
local goal = Workspace.Goal.Position 
local minDistance = 5 -- Minimum distance NPCs should keep from each other, in studs

local function moveNPC(npc)
	local humanoid = npc:FindFirstChild("Humanoid")
	local rootPart = npc:FindFirstChild("HumanoidRootPart")

	if humanoid and rootPart then
		local target = goal - (goal - rootPart.Position).Unit * minDistance
		humanoid.MoveToFinished:Wait()
		humanoid:MoveTo(target)
	end
end

local function checkDistance(npc)
	for _, other in ipairs(NPCs:GetChildren()) do
		if npc ~= other then
			local npcRoot = npc:FindFirstChild("HumanoidRootPart")
			local otherRoot = other:FindFirstChild("HumanoidRootPart")
			if npcRoot and otherRoot then
				local distance = (npcRoot.Position - otherRoot.Position).Magnitude
				if distance < minDistance then
					return false
				end
			end
		end
	end
	return true
end

while true do
	for _, npc in ipairs(NPCs:GetChildren()) do
		if checkDistance(npc) then
			moveNPC(npc)
		end
	end
	wait(1)
end
2 Likes

This is also something I’ve considered, but I’m not sure of an easy way to space them out when pathfinding is still being used when they can’t “see” their target. Thus why I’m thinking of using the system where there are squadrons of AIs where a large group follow one leader who does the pathfinding while the rest determine if they’re flocking or not and such.

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