Is there a way to cancel a pathfind and start a new one

Basically trying to get the bot to pathfind to the nearest player at all times, but


Also not sure why it just decided to start flying but yeah

Heres the code

local Players = game.Players
local DisableAllBots = false
local Debug = false

local PathFindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")

local function FindNearest(NBC)
	local NearestPlayer
	local NearestDistance
	
	for _, Player in (Players:GetPlayers()) do
		if Player.Character and Player.Character.Humanoid and Player.Character.Humanoid.Health ~= 0 then
			local Mag = (Player.Character.HumanoidRootPart.Position - NBC.Position).Magnitude
			
			print(0)
			if Player.Character.IsInSafeZone.Value == false then
				print(1)
				if NearestDistance then
					if Mag < NearestDistance then NearestDistance = Mag; NearestPlayer = Player.Character end
				else
					NearestDistance = Mag; NearestPlayer = Player.Character
				end		
				print(2)
			end
			print(3)
		end
	end
	
	return NearestPlayer, NearestDistance
end

local function pfm(NextBot)
	local Path = PathFindingService:CreatePath({
		
		['AgentRadius'] = 5,
		['AgentHeight'] = 5,
		['AgentCanJump'] = true,
		
		Costs = {
			Water = 20,
			SmoothPlastic = 1,
			ForceField = math.huge,
			Untouchable = math.huge
		}	
	})
	local Waypoints
	local NextWaypointIndex
	local reachedConnection
	local blockedConnection
	
	local NearestPlr, NearestDistance = FindNearest(NextBot.Character)
	
	if not NearestPlr or NearestDistance > NextBot.ChangeableValues.DetectionDistance.Value then
		return "No Near Players"
	else
		local Yes, No = pcall(function()
			Path = PathFindingService:FindPathAsync(NextBot.PrimaryPart.Position, NearestPlr.HumanoidRootPart.Position)
		end)


		if Yes and Path.Status == Enum.PathStatus.Success then
			Waypoints = Path:GetWaypoints()

			blockedConnection = Path.Blocked:Connect(function(BwI)
				if BwI >= NextWaypointIndex then
					blockedConnection:Disconnect()
					pfm(NextBot)
				end
			end)


			for	i, v in ipairs(Waypoints) do

				if v.Action == Enum.PathWaypointAction.Jump then
					NextBot.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
				end

				local Part = Instance.new("Part", workspace.Extras)
				Part.Shape = Enum.PartType.Ball
				Part.Size = Vector3.new(1,1,1)
				Part.Anchored = true
				Part.Position = v.Position
				Part.Material = Enum.Material.Neon
				Part.Color = Color3.new(0,4,0)
				Part.CanCollide = false
				Part.Transparency = 0.5

				NextBot.Humanoid:MoveTo(v.Position)
				NextBot.Humanoid.MoveToFinished:Wait()
			end		
		else
			 if Debug == true then warn("Failed To Compute A Valid Path, Did you make sure that the NextBot Isnt Trapped / Stuck?: " .. if No then No else "Nil") end
		end
	end
end

local function PathFindingMovement(NextBot)
	local Run
	
	while task.wait() do
		if NextBot.Humanoid.Active.Value == true and DisableAllBots == false then
			local D = pfm(NextBot)
			
			if D and Debug == true then
				print(D)
			end			
		else
			break
		end
	end
end
Unedited Code

Just the entire module, if for some reason you would need the rest of the code with it

-- The NextBot Handler Module --
local Players = game.Players
local DisableAllBots = false
local Debug = false

local PathFindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")

-- Functions
local function FindNearest(NBC)
	local NearestPlayer
	local NearestDistance
	
	for _, Player in (Players:GetPlayers()) do
		if Player.Character and Player.Character.Humanoid and Player.Character.Humanoid.Health ~= 0 then
			local Mag = (Player.Character.HumanoidRootPart.Position - NBC.Position).Magnitude
			
			print(0)
			if Player.Character.IsInSafeZone.Value == false then
				print(1)
				if NearestDistance then
					if Mag < NearestDistance then NearestDistance = Mag; NearestPlayer = Player.Character end
				else
					NearestDistance = Mag; NearestPlayer = Player.Character
				end		
				print(2)
			end
			print(3)
		end
	end
	
	return NearestPlayer, NearestDistance
end

local function MoveToMovement(NextBot, ValFol)
	local Stepped
	local NearestPlayer, NearestDistance
	
	Stepped = RunService.Heartbeat:Connect(function(DTime)
		if NextBot.Humanoid.Active.Value == true then
			NearestPlayer, NearestDistance = FindNearest(NextBot.Character)

			if NearestPlayer and NearestDistance then
				if NearestDistance <= ValFol.DetectionDistance.Value then
					NextBot.Humanoid:MoveTo(NearestPlayer.HumanoidRootPart.Position)
				end
			end
		else
			Stepped:Disconnect()
		end
	end)
end

local function pfm(NextBot)
	local Path = PathFindingService:CreatePath({
		
		['AgentRadius'] = 5,
		['AgentHeight'] = 5,
		['AgentCanJump'] = true,
		
		Costs = {
			Water = 20,
			SmoothPlastic = 1,
			ForceField = math.huge,
			Untouchable = math.huge
		}	
	})
	local Waypoints
	local NextWaypointIndex
	local reachedConnection
	local blockedConnection
	
	local NearestPlr, NearestDistance = FindNearest(NextBot.Character)
	
	if not NearestPlr or NearestDistance > NextBot.ChangeableValues.DetectionDistance.Value then
		return "No Near Players"
	else
		local Yes, No = pcall(function()
			Path = PathFindingService:FindPathAsync(NextBot.PrimaryPart.Position, NearestPlr.HumanoidRootPart.Position)
		end)


		if Yes and Path.Status == Enum.PathStatus.Success then
			Waypoints = Path:GetWaypoints()

			blockedConnection = Path.Blocked:Connect(function(BwI)
				if BwI >= NextWaypointIndex then
					blockedConnection:Disconnect()
					pfm(NextBot)
				end
			end)


			for	i, v in ipairs(Waypoints) do

				if v.Action == Enum.PathWaypointAction.Jump then
					NextBot.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
				end

				local Part = Instance.new("Part", workspace.Extras)
				Part.Shape = Enum.PartType.Ball
				Part.Size = Vector3.new(1,1,1)
				Part.Anchored = true
				Part.Position = v.Position
				Part.Material = Enum.Material.Neon
				Part.Color = Color3.new(0,4,0)
				Part.CanCollide = false
				Part.Transparency = 0.5

				NextBot.Humanoid:MoveTo(v.Position)
				NextBot.Humanoid.MoveToFinished:Wait()
			end		
		else
			 if Debug == true then warn("Failed To Compute A Valid Path, Did you make sure that the NextBot Isnt Trapped / Stuck?: " .. if No then No else "Nil") end
		end
	end
end

local function PathFindingMovement(NextBot)
	local Run
	
	while task.wait() do
		if NextBot.Humanoid.Active.Value == true and DisableAllBots == false then
			local D = pfm(NextBot)
			
			if D and Debug == true then
				print(D)
			end			
		else
			break
		end
	end
end

-- Module
local Nbot = {}

Nbot.Setup = function(NextBot)
	NextBot.PrimaryPart:SetNetworkOwner(nil)
	local ValFol = NextBot.ChangeableValues

	local NextBotSpeed = ValFol.Speed.Value
	local NextBotJumpPower = ValFol.JumpPower.Value
	local NextBotHealth = ValFol.Health.Value
	local CanBeKilled = ValFol.CanBeKilled.Value
	local Pic = ValFol.Image.Value
	
	local NBotHumanoid = NextBot.Humanoid
	
	NBotHumanoid.WalkSpeed = NextBotSpeed
	NBotHumanoid.JumpPower = NextBotJumpPower
	
	if CanBeKilled == true then
		NBotHumanoid.MaxHealth = NextBotHealth; NBotHumanoid.Health = NextBotHealth
	else
		local ff = Instance.new("ForceField", NextBot)
		ff.Visible = false
		NBotHumanoid.MaxHealth = math.huge; NBotHumanoid.Health = math.huge
	end
	
	NextBot.Character.Front.ImageLabel.Image = "rbxassetid://" .. Pic
	NextBot.Character.Back.ImageLabel.Image = "rbxassetid://" .. Pic
	
	if not NextBot.Humanoid:GetAttribute("Active") then
		NextBot.Humanoid:SetAttribute("Active", false)
	end
	
	return "Setup Complete"
end

Nbot.Start = function(NextBot)
	local ValFol = NextBot.ChangeableValues
	NextBot.Humanoid.Active.Value = true

	if ValFol.SmartAi.Value == true then
		PathFindingMovement(NextBot)
		print("Smart Movement Activated")
	else
		MoveToMovement(NextBot, ValFol)
		print("Basic Movement Activated")
	end	
	
end

Nbot.Stop = function(NextBot)
	NextBot.Humanoid.Active.Value = false
end

Nbot.DisableAllBots = function(A)
	if A then
		print("This function doesnt require anything to be sent, disables all bots")
	end
	
	if DisableAllBots == true then
		print("Bots are already disabled")
		return "Failed, Bots Are Disabled Already"
	end
	DisableAllBots = true
	return "Bots Disabled"
end

Nbot.EnableAllBots = function(A)
	if A then
		print("This function doesnt require anything to be sent, enables all bots")
	end

	if DisableAllBots == false then
		print("Bots are already enabled")
		return "Failed, Bots Are Enabled Already"
	end
	DisableAllBots = false
	return "Bots Enabled"
end

return Nbot
1 Like

I think that what causes the character to fly is that you use Humanoid:ChangeState() instead you can use Humanoid.Jump = true

Also if you need help with pathfinding here is a good tutorial

Personally, I do something like this:

local target = NearestPlr.HumanoidRootPart.Position
local pos = NextBot.PrimaryPart.Position
local hum = NextBot:FindFirstChildWhichIsA("Humanoid")

for	i,v in ipairs(Waypoints) do
	if v.Action == Enum.PathWaypointAction.Jump then
		hum.Jump = true
	end

	local Part = Instance.new("Part", workspace.Extras)
	Part.Shape = Enum.PartType.Ball
	Part.Size = Vector3.new(1,1,1)
	Part.Anchored = true
	Part.Position = v.Position
	Part.Material = Enum.Material.Neon
	Part.Color = Color3.new(0,4,0)
	Part.CanCollide = false
	Part.Transparency = 0.5

	hum:MoveTo(v.Position)
	local check = hum.MoveToFinished:Wait()
	
	if not check then -- CHECKS IF BOT IS STUCK
		pfm(NextBot) --RECALCULATE
		break
	end
	
	if (Waypoints[#Waypoints].Position - target).Magnitude > 5 then -- CHECKS IF PLAYER HAS MOVED AWAY FROM GOAL POSITION OF WAYPOINTS
		pfm(NextBot) -- RECALCULATE
		break
	end
end		

Basically, you call the function again and break the current waypoint loop.

Dont know if i set it up right but changed it to

local function pfm(NextBot)
	local Path = PathFindingService:CreatePath({
		
		['AgentRadius'] = 5,
		['AgentHeight'] = 5,
		['AgentCanJump'] = true,
		
		Costs = {
			Water = 20,
			SmoothPlastic = 1,
			ForceField = math.huge,
			Untouchable = math.huge
		}	
	})
	local Waypoints
	local NextWaypointIndex
	local reachedConnection
	local blockedConnection
	
	local NearestPlr, NearestDistance = FindNearest(NextBot.Character)
	
	if not NearestPlr or NearestDistance > NextBot.ChangeableValues.DetectionDistance.Value then
		return "No Near Players"
	else
		local Yes, No = pcall(function()
			Path = PathFindingService:FindPathAsync(NextBot.PrimaryPart.Position, NearestPlr.HumanoidRootPart.Position)
		end)


		if Yes and Path.Status == Enum.PathStatus.Success then
			Waypoints = Path:GetWaypoints()

			blockedConnection = Path.Blocked:Connect(function(BwI)
				if BwI >= NextWaypointIndex then
					blockedConnection:Disconnect()
					pfm(NextBot)
				end
			end)


			for	i, v in ipairs(Waypoints) do

				if v.Action == Enum.PathWaypointAction.Jump then
					NextBot.Humanoid.Jump = true
				end

				local Part = Instance.new("Part", workspace.Extras)
				Part.Shape = Enum.PartType.Ball
				Part.Size = Vector3.new(1,1,1)
				Part.Anchored = true
				Part.Position = v.Position
				Part.Material = Enum.Material.Neon
				Part.Color = Color3.new(0,4,0)
				Part.CanCollide = false
				Part.Transparency = 0.5

				NextBot.Humanoid:MoveTo(v.Position)
				local Check = NextBot.Humanoid.MoveToFinished:Wait()
				
				if not Check then
					pfm(NextBot)
					break
				end
				
				if (Waypoints[#Waypoints].Position - NearestPlr.HumanoidRootPart.Position).Magnitude > NextBot.ChangeableValues.DetectionDistance.Value then
					pfm(NextBot)
					break
				end
			end		
		else
			 if Debug == true then warn("Failed To Compute A Valid Path, Did you make sure that the NextBot Isnt Trapped / Stuck?: " .. if No then No else "Nil") end
		end
	end
end

and i dont think anything changed, it still goes all the way to the players last position
Also i tried putting prints under the stuff that was added, and it never printed a single one of them

Idk if the breaks were spose to break the loop or anything, as i have the loop handled in another function

local function PathFindingMovement(NextBot)
	local Run
	
	while task.wait() do
		if NextBot.Humanoid.Active.Value == true and DisableAllBots == false then
			local D = pfm(NextBot)
			
			if D and Debug == true then
				print(D)
			end			
		else
			break
		end
	end
end

Alright ive taken a look at it and
The main difference i see is that you use runservice

previously in another post i was asking what to do about visualizing the path and it just created a ton of parts, dropping fps a bit

Although i might just have to give in and just use runservice and just not visualize the path

The reason on why i have used RUN service, is that to give the NPC a nice smooth path, instead of using a while true do loop.