Pathfinding keeps making short stops

I made a pathfinding module and even made it check if the player/target moves or not, but there’s a problem

the ai for some reason whenever the pathfinding is reset for any reason it just stopes moving for a very little amount of time and then goes back to chasing, which makes it overall more annoying to use

Part of the module that does the chasing logic
function module.moveToWaypoints(maxWaypointsBeforeReset, waypointDistCheckFrequency, humanoid:Humanoid, agents, startPos:Vector3, endPos:BasePart, useMoveTo) 
	local path:Path, waypoints:{PathWaypoint} = module.createPath(agents, startPos, endPos.Position)
	

	if path and waypoints and humanoid.Health > 0 then
		for i,v:PathWaypoint in pairs(waypoints) do
						
			if i ~= 1 and i < maxWaypointsBeforeReset then
				if useMoveTo then
					module.HumanoidMoveTo(humanoid,v.Position)
				else
					module.HumanoidMove(humanoid,startPos,v.Position)
				end

				if agents.AgentCanJump then
					if v.Action == Enum.PathWaypointAction.Jump and humanoid:GetState() ~= Enum.HumanoidStateType.Jumping and i ~= 2 then
						--task.wait(16/humanoid.WalkSpeed/10)
						--humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
						humanoid.Jump = true
					end
				end
				
				-- i use this instead of MoveToFinished so i can check if the humanoid is too far away or not from where it's supposed to be, signaling if it's blocked or not
				local yield = math.abs((v.Position - waypoints[i-1].Position).Magnitude)/1.65 * 1.6/humanoid.WalkSpeed
				task.wait(yield)
				--humanoid.MoveToFinished:Wait()
				
				log("Waypoint "..i.." cycle ended in "..yield.." seconds! Time for checking.")

				if i % waypointDistCheckFrequency == 0 and i >= waypointDistCheckFrequency then -- check if i is dividible by maxWaypointsBeforeDistCheck
					local player_check = math.abs(
						(
							v.Position - 
								humanoid.Parent:FindFirstChild("HumanoidRootPart").Position
						).Magnitude
					)
					
					local is_too_far_from_wpoint = player_check > agents.AgentHeight * 1.5
					
					if is_too_far_from_wpoint == true or math.abs((waypoints[#waypoints].Position - endPos.Position).Magnitude) > #waypoints-i/5*agents.WaypointSpacing then
						logWARN("ERROR: WAYPOINT INDEX "..i.." IS TOO FAR FROM NPC TO BE COUNTED OR END POINT HAS MOVED BY TOO MUCH.")
						
						--if is_too_far_from_wpoint == true then print(("man.")) end
						
						--waypoints:Destroy()

						--task.spawn(function()
						--	module.moveToWaypoints(maxWaypointsBeforeReset, waypointDistCheckFrequency, humanoid, agents, humanoid.Parent:FindFirstChild("HumanoidRootPart").Position, endPos, useMoveTo)
						--end)
						
						
						return
					end
				end
				path.Blocked:Connect(function(blockedWaypoint)
					logWARN("ERROR: WAYPOINT INDEX "..blockedWaypoint.." IS BLOCKED.")
					--waypoints:Destroy()

					--module.moveToWaypoints(maxWaypointsBeforeReset, maxWaypointsBeforeDistCheck, humanoid, agents, humanoid.Parent:FindFirstChild("HumanoidRootPart").Position, endPos, useMoveTo) -- uncomment to make pathfinding recompute to same end!
					
					return
				end)
			end

		end
	else
		logWARN("ERROR: FUNCTION IS EITHER MISSING PATH OR WAYPOINT, OR PROVIDED HUMANOID IS DEAD.")
		return
	end
end
The code that executes the module
--// This code will make every ncp in a table chase the nearest player, but the module can also be called from the model itself, check example inside Pathfinding3 (the npc in workspace)

local checkClosestModule = require(game.ServerScriptService.CheckClosestModule)
local pathfindingModule = require(game.ServerScriptService.PathfindingModule)

local is_executing = false

local ennemies = {
	{
		["Enemy"] = workspace.Pathfinding3,
		["AgentHeight"] = 6,
		["AgentWidth"] = 4,
		["WaypointSpacing"] = 4,
		["Costs"] = {
			Decoration = 100
		},
		["MaxDist"] = 200
	}
}

--while task.wait() do
for _,v in pairs(ennemies) do
	task.spawn(function()
		while task.wait() do

			--if not game.Players:FindFirstChildOfClass("Player") then task.wait(.5) end

			--game:GetService("RunService").Heartbeat:Wait()


			local distArray = checkClosestModule.findClosest(game.Players, v.Enemy.PrimaryPart)

			--print(distArray)

			local chosenPlayer = 0

			for i = 1, 3 do
				local instance = distArray[i]

				if instance and instance[2] and instance[2] <= v.MaxDist and chosenPlayer == 0 then
					chosenPlayer = i
					continue
				end
			end

			if chosenPlayer ~= 0 then

				if not is_executing then
					is_executing = true
					pathfindingModule.moveToWaypoints(
						math.huge,
						4, -- making this lower will make it turn more, at the expense of freezing a bit more idk how to fix that ._.
						v.Enemy.Humanoid,
						{
							AgentHeight = v.AgentHeight,
							AgentWidth = v.AgentWidth,
							AgentCanJump = true,
							AgentCanClimb = true,
							WaypointSpacing = v.WaypointSpacing,
							Costs = v.Costs
						},
						v.Enemy:GetPivot().Position,
						distArray[chosenPlayer][1].PrimaryPart,
						true
					)
					is_executing = false
				end

			end
		end
	end)

end
--end

for reference, both the player and the ai go at 25 WalkSpeed

Any help is appreciated! (also sorry if the code is messy and has lots of random lines that were set as comments i did a lot of fiddling prior and I just couldn’t find a solution hence why I’m making this post.)

Try setting the network owner of the NPC to server and see what changes.

local NPC = workspace.NPC.HumanoidRootPart -- The NPC
NPC:SetNetworkOwner(nil) -- Gives the server network ownership
1 Like

It’s all about leftover time to reach the waypoint and the waypoint spacing compared to a full stride of the walking or running animation. It’s very challenging to eliminate that slight pause.

1 Like

I FIXED IT!!!

I just moved the function that does the waiting below the check for player movement and it works like a charm!!!
I’m gonna set your answer as the solution because sadly setting the network owner to the server didn’t do much

1 Like

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