Pathfinding AI kinda laggy and sometimes stop for no reason

Sooo, i tried to make a pathfinding AI that updates the path whenever the target moves to another place.
but, sometimes the AI just Stop and after a few seconds the AI start lagging.
Video : https://youtu.be/CRKoOv_ml3U
Game Link if you want to try it yourself : My New RPG - Roblox

AI Script

local oldpos = character.PrimaryPart.Position
local pathfindservice = game:GetService("PathfindingService")
local waypointindex
local breaking = false
local function backto(waypoint)
	for i = 1,#waypoint do
		if script.Parent.Value == nil then
			if waypoint[i].Action == Enum.PathWaypointAction.Jump then
				character.Humanoid.Jump = true
			else
				character.Humanoid:MoveTo(waypoint[i].Position)
				character.Humanoid.MoveToFinished:Wait()
			end
		else
			break
		end
	end
end
local function walkpoint(waypoint)
	for i = 1,#waypoint do
		if breaking == false and script.Parent.Value ~= nil then
		if waypoint[i].Action == Enum.PathWaypointAction.Jump then
			character.Humanoid.Jump = true
		else
			character.Humanoid:MoveTo(waypoint[i].Position)
			if (waypoint[#waypoint].Position - script.Parent.Value.PrimaryPart.Position).Magnitude <= 6 then
				print("near waypoint")
				if (script.Parent.Value.PrimaryPart.Position - character.PrimaryPart.Position).Magnitude > character.AggroRange.Value then
					script.Parent.Value = nil
				end
				character.Humanoid.MoveToFinished:Wait()
			else
				print("Breaking the loop")
				breaking = true
			end
		end
		else
			breaking = false
			break
		end
	end
end
while wait(0.1) do
	if script.Parent.Value ~= nil then
		print("Target Found!")
		local path = pathfindservice:CreatePath()
		path:ComputeAsync(character.PrimaryPart.Position,script.Parent.Value.PrimaryPart.Position)
		if path.Status == Enum.PathStatus.Success then
			local waypoint = path:GetWaypoints()
			walkpoint(waypoint)
		end
		--print("Waypoint Distance Between Player "..(waypoint[#waypoint].Position - script.Parent.Value.PrimaryPart.Position).Magnitude)
	else
		--print("Target Not Found")
		local path = pathfindservice:CreatePath()
		path:ComputeAsync(character.PrimaryPart.Position,oldpos)
		local waypoint
		if path.Status == Enum.PathStatus.Success then
			local waypoint = path:GetWaypoints()
			backto(waypoint)
		end
	end
	if script.Parent.Value == nil then
		for i,v in pairs(workspace:GetChildren()) do
			if v:FindFirstChild("Humanoid") then
				if v:FindFirstChild("Team") then
					if v.Team.Value ~= character.Team.Value then
						if (character.PrimaryPart.Position - v.PrimaryPart.Position).Magnitude <= character.AggroRange.Value then
						script.Parent.Value = v
						end
					end
				end
			end
		end
	end
end
script.Parent.Changed:Connect(function()
	print("Target Changed!")
end)```

`
2 Likes

When posting code, format it by using “```” at the start and end of the code.

2 Likes

oh ok, thx, i didn’t know about that

So… after researching a little bit, and use some prints, i know what makes the AI stops.
it’s the Break Command at the Walkpoints Function, so now i already fixed the AI stops by using repeat loops, and set the target to nil if the repeat loops broke.
so now the AI will no longer stops for no reason, but it still stutter.
and i don’t know what causing it to stutter.
the new code:

local oldpos = character.PrimaryPart.Position
local pathfindservice = game:GetService("PathfindingService")
local waypointindex
local breaking = false
local function backto(waypoint)
	for i = 1,#waypoint do
		if script.Parent.Value == nil then
			if waypoint[i].Action == Enum.PathWaypointAction.Jump then
				character.Humanoid.Jump = true
			else
				character.Humanoid:MoveTo(waypoint[i].Position)
				character.Humanoid.MoveToFinished:Wait()
			end
		else
			break
		end
	end
end
local function walkpoint(waypoint)
	for i = 1,#waypoint do
		if script.Parent.Value ~= nil then
		if waypoint[i].Action == Enum.PathWaypointAction.Jump then
			character.Humanoid.Jump = true
		else
			character.Humanoid:MoveTo(waypoint[i].Position)
			if (waypoint[#waypoint].Position - script.Parent.Value.PrimaryPart.Position).Magnitude <= 6 then
				--print("near waypoint")
				if (script.Parent.Value.PrimaryPart.Position - character.PrimaryPart.Position).Magnitude > character.AggroRange.Value then
					script.Parent.Value = nil
				end
				repeat
					wait()
					--print("Waiting till the npc is near")
				until (character.PrimaryPart.Position - waypoint[i].Position).Magnitude <= 4
			end
		end
		end
		if script.Parent.Value ~= nil then
			if (waypoint[#waypoint].Position - script.Parent.Value.PrimaryPart.Position).Magnitude > 6 then
				break
			end
		end
	end
end
script.Parent.Changed:Connect(function()
	--print("While Wait Complete!")
	if script.Parent.Value ~= nil then
	repeat
	if script.Parent.Value ~= nil then
		--print("Target Found!")
		local path = pathfindservice:CreatePath()
		path:ComputeAsync(character.PrimaryPart.Position,script.Parent.Value.PrimaryPart.Position)
		if path.Status == Enum.PathStatus.Success then
			local waypoint = path:GetWaypoints()
			walkpoint(waypoint)
		else
			character.Humanoid:MoveTo(script.Parent.Value.PrimaryPart.Position)
		end
		--print("Waypoint Distance Between Player "..(waypoint[#waypoint].Position - script.Parent.Value.PrimaryPart.Position).Magnitude)
	else
		--print("Target Not Found")
		local path = pathfindservice:CreatePath()
		path:ComputeAsync(character.PrimaryPart.Position,oldpos)
		local waypoint
		if path.Status == Enum.PathStatus.Success then
			local waypoint = path:GetWaypoints()
			backto(waypoint)
		else
			character.Humanoid:MoveTo(oldpos)
		end
	end
	until (script.Parent.Parent.PrimaryPart.Position - script.Parent.Value.PrimaryPart.Position).Magnitude > script.Parent.Parent.AggroRange.Value
	script.Parent.Value = nil
	end
end)

while wait() do
	if script.Parent.Value == nil then
		for i,v in pairs(workspace:GetChildren()) do
			if v:FindFirstChild("Humanoid") then
				if v:FindFirstChild("Team") then
					if v.Team.Value ~= character.Team.Value then
						if (character.PrimaryPart.Position - v.PrimaryPart.Position).Magnitude <= character.AggroRange.Value then
							if v.Humanoid.Health > 0 then
								script.Parent.Value = v
							end
						end
					end
				end
			end
		end
	else
	end
end

Is the stuttering to do with the motion?
Using prints can you generate a list of the steps taken as in moveto walkpoint backto
and any I have missed.
This would give you a way to see more clearly where exactly in the script the stuttering is occurring.

1 Like

Ok, so after i print the walkpoint, the stuttering happens because the AI moves a bit by bit
like there’s a delay
for example:
total walkpoint = 20
after that the AI will go like this
moveto(walkpoint[1])
then a delay comes
moveto(walkpoint[2])
and so on… till it reaches 20
but i still dont know where the delay comes from.
Edit:
The delay comes after the function repeated for about 10 times.

It’s most likely just lag with the pathfinding service itself, since it does take some time to formulate paths. I really don’t know what to suggest to make it better, try messing around with loading it and moving to it and that may lead you to something.

1 Like

OK, i fixed the stuttering, now it work GREAT! thanks to runservice!

local runservice = game:GetService("RunService")
local path = pathfind:CreatePath()
runservice.Heartbeat:Connect(function()
	if script.Parent.Value ~= nil then
		path:ComputeAsync(script.Parent.Parent.PrimaryPart.Position,script.Parent.Value.PrimaryPart.Position)
		if path.Status == Enum.PathStatus.Success then
			local wypoint = path:GetWaypoints()
			for i = 1,#wypoint do
				script.Parent.Parent.Humanoid:MoveTo(wypoint[i].Position)
				if (script.Parent.Value.PrimaryPart.Position - wypoint[#wypoint].Position).Magnitude > 20 then
					break
				end
				repeat wait() until (script.Parent.Parent.PrimaryPart.Position-wypoint[i].Position).Magnitude < 6
			end
		end
	end
end)
4 Likes