How do I keep generating path?

I have this script the creates a path for NPCs in my game to use. But currently they will only generate the path once, so if let’s say there we’re to appear something infront of it, then the NPC will just keep walking into the wall.
Is there a way for the NPC to keep calculating the path?

This is the code I’m currently using

function MoveNPC(npcPart, npcPathFolder)
	local waypoints = npcPathFolder:GetChildren()
	local agentParams = nil

	if Settings["TowerNPCNames"][npcPart.Name] then
		agentParams = Settings["TowerAgentParams"]
	else
		agentParams = Settings["AgentParams"]
	end

	local currentWaypointIndex = 1

	local currentWaypoint = waypoints[currentWaypointIndex]

	local nextWayPointIndex
	local reachedConnection
	local blockedConnection

	local currentWaypointIndex = 1

	local Walkspeed = npcPart:GetAttribute("Walkspeed")
	local animator = Instance.new("Animator", npcPart.Humanoid)
	local idleAnimation = animator:LoadAnimation(ReplicatedStorage.Storage.Animations.Idle)
	local runAnimation = nil

	if Walkspeed < 16 then
		runAnimation = animator:LoadAnimation(ReplicatedStorage.Storage.Animations.Walk)
	elseif Walkspeed >= 16 then
		runAnimation = animator:LoadAnimation(ReplicatedStorage.Storage.Animations.Run)
	end

	local idleAnimation2 = animator:LoadAnimation(ReplicatedStorage.Storage.Animations.Idle2)
	idleAnimation.Priority = Enum.AnimationPriority.Idle
	idleAnimation2.Priority = Enum.AnimationPriority.Idle
	runAnimation.Priority = Enum.AnimationPriority.Movement
	idleAnimation:Play()

	local controller = npcPart:FindFirstChildOfClass("Humanoid")

	local humanoid = npcPart:FindFirstChild("Humanoid")
	humanoid.WalkSpeed = Walkspeed

	for i, v in pairs(npcPart:GetDescendants()) do
		if v:IsA("BasePart") then
			v:SetNetworkOwner(nil)
		end
	end

	local function getPath(destination)
		local path = getPathCache(npcPart.PrimaryPart.Position, destination.Position, agentParams)

		if npcPart ~= nil and npcPart:FindFirstChild("HumanoidRootPart") then
			Paths[npcPart] = path
			path:ComputeAsync(npcPart.PrimaryPart.Position, destination.Position)
		end

		return path
	end

	local function walkTo(destination)
		local path = getPath(destination)

		if path.Status == Enum.PathStatus.Success then
			if Settings["VisualizePath"] then
				if not workspace.VisualPoints:FindFirstChild(npcPart.Name) then
					local folder = Instance.new("Folder")
					folder.Name = npcPart.Name
					folder.Parent = workspace.VisualPoints
				else
					workspace.VisualPoints:FindFirstChild(npcPart.Name):Destroy()
					local folder = Instance.new("Folder")
					folder.Name = npcPart.Name
					folder.Parent = workspace.VisualPoints
				end

				local function getRandomNumber(minNumber, maxNumber)
					return math.floor(math.random(minNumber, maxNumber))
				end

				if not PathColors[npcPart.Name] then
					PathColors[npcPart.Name] = Color3.fromRGB(getRandomNumber(0, 255), getRandomNumber(0, 255), getRandomNumber(0, 255))
				end
				local pathColor = PathColors[npcPart.Name]

				for index, waypoint in pairs(path:GetWaypoints()) do
					local visualPart = Instance.new("Part")
					visualPart.Anchored = true
					visualPart.Size = Vector3.new(1,1,1)
					visualPart.Color = pathColor
					visualPart.CanCollide = false
					visualPart.CanTouch = false
					visualPart.Parent = workspace.VisualPoints:FindFirstChild(npcPart.Name)
					visualPart.Position = waypoint.Position
				end
			end

			for index, waypoint in pairs(path:GetWaypoints()) do
				humanoid:MoveTo(waypoint.Position)
				humanoid.MoveToFinished:Wait()
			end
		else
			if npcPart ~= nil and npcPart:FindFirstChild("HumanoidRootPart") then
				runAnimation:Play()
				humanoid:MoveTo(destination.Position - (npcPart.HumanoidRootPart.CFrame.LookVector * -10))
				task.wait(2)
				runAnimation:Stop()
			end
		end
	end

	local function Patrol()
		local currentWaypoint = waypoints[currentWaypointIndex]
		if not npcPart:FindFirstChildOfClass("Humanoid") then return end

		if not runAnimation.IsPlaying and npcPart.Humanoid.WalkSpeed > 0 then
			runAnimation:Play(.1)
		end


		walkTo(currentWaypoint)

		if currentWaypoint:FindFirstChild("WaitTime") then
			idleAnimation:Stop(0.4)
			local WaitTimeValue = currentWaypoint.WaitTime.Value
			runAnimation:Stop(0.1)
			idleAnimation2:Play()
			task.wait(idleAnimation2.Length)
			idleAnimation2:Stop(0.4)
			idleAnimation:Play()
			task.wait(WaitTimeValue - idleAnimation2.Length)
		end

		currentWaypointIndex = currentWaypointIndex + 1
		if currentWaypointIndex > #waypoints then
			currentWaypointIndex = 1
		end
	end

	while task.wait() do
		Patrol()
	end
end
1 Like

Instead of constantly calculating a new path why not generate one when the path is blocked?
You can use Path.Blocked to achieve this. After its fired just generate and return a new path for the NPC to follow.

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