How can I make AI stay in the middle of the paths

I’m trying to make Tower Defense AI with pathfinding and I cannot figure out how to keep them in the middle of the paths.

local pathfinding = game:GetService("PathfindingService")

local function findPath(hrp : BasePart,location : Vector3)
	local path : Path = pathfinding:CreatePath({
		AgentCanJump = false,
		AgentCanClimb = false,
		AgentRadius = 3,
		Costs = {
			Brick = 0,
			Plastic = math.huge
		}
	})
	path:ComputeAsync(hrp.Position,location)
	return path
end

while task.wait(3) do
	for i = 1,3 do
		local monster = game.ReplicatedStorage:WaitForChild("monster"):Clone()
		monster.Parent = workspace
		monster.HumanoidRootPart.CFrame = workspace:WaitForChild("Spawn"..math.random(1,2)).CFrame

		task.spawn(function()
			local path : Path = findPath(monster.HumanoidRootPart,workspace.End.Position)
			for i,points : PathWaypoint in pairs(path:GetWaypoints()) do
				monster.Humanoid:MoveTo(points.Position)
				monster.Humanoid.MoveToFinished:Wait()
			end
			monster:Destroy()
		end)
		
		task.wait(.5)
	end
end
1 Like

Considering pathfinding is more about calculating the optimal path over the intended one, there’s two things I think you can do.

  1. Add invisible parts that forces them to follow the middle (and you could probably tamper with the collision groups so that only they collide with it, and pathfinding should ideally work with it, and changing the agent settings should help)

  2. Opt-in for using MoveTo() directly and have them move to parts along a predefined path with parts (basically name them 1-4 and have that be the path)
    image

dry wrote this so apologies if there’s a mistake

-- obviously not the most optimal way to make an ordered path but just for demo
local nodes = workspace:WaitForChild("path1")

path1 = { -- assumes these numbers are part names in a model/folder
   nodes["1"],
   nodes["2"],
   nodes["3"],
   nodes["4"]
}

-- Pass a list for the humanoid to follow
local function followRoute(MonsterCharacter, routList)
   local Humanoid = MonsterCharacter:WaitForChild("Humanoid")
   for _, node in ipairs(routList) do
      Humanoid:MoveTo(node.Position)
      Humanoid.MoveToFinished:Wait()
   end
end

followRoute([character clone you want], path1)

1 Like

i’m fully aware on how to use the 2nd option, but it’s so time consuming. And that method wouldn’t work if i wanted multiple spawners.