Creating random AI paths using PathfindingService

I’m trying to create random routes/paths for my NPC’s in my game. I tried creating lots of point parts in a folder and then looping through all NPC’s to locate the nearest point to the single of them. I then used Humanoid:MoveTo() to make the NPC walk to the point. But after the NPC’s had walk between the points the NPC’s began suddenly to stop at random points even though all of my points were in reach of the NPC. I don’t think my (locating the nearest point to then make the NPC walk to) is the most efficient way to create AI paths and that’s why I’m writing this article so I can hear some of your ideas. I will leave my scripts here anyways.

Video of my pathfinding system in use:

robloxapp-20210210-2101410.wmv (91.3 KB)

local function Search()
	local FindPath = workspace.Path:GetChildren()
	local Minimum = nil
	local ClosestPath = nil

	for i = 1, #FindPath do

		local Humanoid = script.Parent:FindFirstChild("Humanoid")
		local Body = script.Parent:FindFirstChild("HumanoidRootPart") or script.Parent:FindFirstChild("UppperTorso")

		if Body then 

			local Magnitude = (FindPath[i].Position - Body.Position).magnitude

			if Minimum == nil or Magnitude < Minimum or Minimum < 10 then					

				Minimum = Magnitude
				ClosestPath = FindPath[i]

			end

		end

	end

	if Minimum then
				
		if Minimum < 500 then

			return ClosestPath
			
		end

	end
		
end

while wait() do
	
	local ClosestPath = Search()
	
	if ClosestPath then
				
		-- get pathfinding service
		local pathfindingService = game:GetService("PathfindingService")

		-- Variables for NPC humanoid, torso, and destination
		local Humanoid = script.Parent:FindFirstChild("Humanoid")
		local Body = script.Parent:FindFirstChild("HumanoidRootPart") or script.Parent:FindFirstChild("UppperTorso")
		local Destination = ClosestPath.Position

		-- create path object
		local Path = pathfindingService:CreatePath()

		-- compute a path
		Path:ComputeAsync(Body.Position, Destination, math.huge)

		-- get the waypoints table
		local Waypoints = Path:GetWaypoints()

		-- iterate through all waypoints, and jump when necessary
		for k, Waypoint in pairs(Waypoints) do
			Humanoid:MoveTo(Waypoint.Position)

			-- change humanoid state to jump if necessary
			if Waypoint.Action == Enum.PathWaypointAction.Jump then
				Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			end

			Humanoid.MoveToFinished:Wait()
		end

	end

end
1 Like

Hey! I have editted some of the components in your scripts. I think the thing that makes it not function is that your defining pathfindingservice inside the while loop. Oh yeah and I also implement a better way of finding random nodes. Here is the new script:

local nodes = game.Workspace.Nodes
local pathfind = game:GetService("PathfindingService")
local character = game.Workspace.Humanoid

local function Search()
	local FindPath = nodes:GetChildren()
	local Minimum = nil
	local ClosestPath = nil

	for i = 1, #FindPath do

		local Humanoid = character:FindFirstChild("Humanoid")
		local Body = character.Torso

		if Body then 

			local Magnitude = (FindPath[i].Position - Body.Position).magnitude

			if Minimum == nil or Magnitude < Minimum or Minimum < 10 then					

				Minimum = Magnitude
				ClosestPath = FindPath[i]

			end
		end
	end
	if Minimum then
		if Minimum < 500 then
			return ClosestPath
		end
	end
end

while wait() do

	local ClosestPath = Search()

	if ClosestPath then

		-- get pathfinding service

		-- Variables for NPC humanoid, torso, and destination
		local Humanoid = character:FindFirstChild("Humanoid")
		local items = nodes:GetChildren()
		local randomItem = items[math.random(1, #items)]
		
		local Destination = randomItem.Position

		-- create path object
		local Path = pathfind:CreatePath()

		-- compute a path
		Path:ComputeAsync(character.Torso.Position, Destination)

		-- get the waypoints table
		local Waypoints = Path:GetWaypoints()

		-- iterate through all waypoints, and jump when necessary
		for k, Waypoint in pairs(Waypoints) do
			Humanoid:MoveTo(Waypoint.Position)

			-- change humanoid state to jump if necessary
			if Waypoint.Action == Enum.PathWaypointAction.Jump then
				Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			end

			Humanoid.MoveToFinished:Wait()
		end
	end
end

image

2 Likes