Pathfinding problem

Hi there.
I’m currently working on an improved AI system for my game and everything’s been working fine except for one thing, pathfinding. So basically I have an enemy that can attack you, run towards you, and pathfind to you if he can’t see you. The problem with pathfinding with this is that it works for some time (30 seconds maybe) and then the enemy for some reason just can’t pathfind more and gets stuck in one place. There is a video down below if my explanation sounds confusing.

Here is the code for the enemy:

local runService = game:GetService("RunService")

wait(4)

local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local root = char:WaitForChild("HumanoidRootPart")

local target = nil
local distance = nil

local attackDistance = 2
local maxChasingDistance = 50

char.PrimaryPart:SetNetworkOwner(nil)
hum.BreakJointsOnDeath = false

local currentState = "Patroling"

local pathFindFails = 0

local pathParams = {
	["AgentRadius"] = 4,
	["AgentHeight"] = 5.11,
	["AgentCanJump"] = true
}

local function FindTarget()
	local closestDist = 0
	local closestPlayer = nil
	local firstIteration = true

	for i,player in ipairs(game.Players:GetChildren()) do
		if  firstIteration then
			if char and char:FindFirstChild("Humanoid") and player and player.Character and player.Character.Humanoid.Health > 0 then
				closestDist = (player.Character.HumanoidRootPart.Position - char.HumanoidRootPart.Position).Magnitude
				closestPlayer = player
				firstIteration = false
			end
		else
			if char and char:FindFirstChild("Humanoid") and player and player.Character and player.Character.Humanoid.Health > 0 then
				if(player.Character.HumanoidRootPart.Position - char.HumanoidRootPart.Position).Magnitude < closestDist then
					closestDist = (char.HumanoidRootPart.Position - player.Character.HumanoidRootPart.Position ).Magnitude
					closestPlayer = player
				end
			end
		end
	end

	if  closestPlayer and (char.HumanoidRootPart.Position -  closestPlayer.Character.HumanoidRootPart.Position).Magnitude < 100 then
		return  closestPlayer.Character
	else
		return nil
	end
end

local function CheckSight(target)
	local rayCastParams = RaycastParams.new()
	rayCastParams.FilterType = Enum.RaycastFilterType.Blacklist
	rayCastParams.FilterDescendantsInstances = {char}

	local direction = (target.HumanoidRootPart.Position - root.Position).Unit * 200
	local rayCastResult = workspace:Raycast(char.HumanoidRootPart.Position,  direction, rayCastParams)

	if rayCastResult then
		if rayCastResult.Instance:IsDescendantOf(target) then
			return true
		end
	else
		return false
	end
end

local function GetUnstuck()
	hum:MoveTo(Vector3.new(root.Position.X + math.random(-1, 1), 0, root.Position.Z + math.random(-1, 1)))
	wait(1)
end
local canPathFind = true

--Pathfinding function
local function PathToTarget(target)
	local path = game:GetService("PathfindingService"):CreatePath(pathParams)
	path:ComputeAsync(root.Position, target.HumanoidRootPart.Position)
	local wayPoints =  path:GetWaypoints()
	if path.Status == Enum.PathStatus.Success then
		for i,v in ipairs(wayPoints) do
			if v.Action == Enum.PathWaypointAction.Jump then
				hum.Jump = true
			else
				hum:MoveTo(v.Position)
				local coro = coroutine.wrap(function()
					wait(0.5)
					if hum.WalkToPoint.Y > root.Position.Y then
						hum.Jump = true
					end
				end)
				coro()
				hum.MoveToFinished:Wait()
			end
			if (CheckSight(target) == false) and math.abs(root.Position.Y - target.HumanoidRootPart.Position.Y) > 1.5 then
				break
			elseif (target.HumanoidRootPart.Position - wayPoints[#wayPoints].Position).Magnitude > 30 then
				break
			elseif math.abs(root.Position.Y - v.Position.Y) > 10 then
				break
			elseif (root.Position - v.Position).Magnitude > 10 then
				break
			end

			local timeOut = hum.MoveToFinished:Wait()
			if not timeOut then
				GetUnstuck()
				break
			end
		end
	else
		print("Failed to generate a path")
		GetUnstuck()
		pathFindFails = pathFindFails + 1
		if pathFindFails > 10 then
			GetUnstuck()
			pathFindFails = 0
		end
	end
end
----------

-- State functions
local canPatrol = true
local function Patroling()
	if target and CheckSight(target) then
		currentState = "Running"
	end
	hum.WalkSpeed = 16
	if canPatrol then
		canPatrol = false
		hum:MoveTo(root.Position + Vector3.new(math.random(-20, 20), 0, math.random(-20, 20)))
		hum.MoveToFinished:Wait()
		wait(math.random(1, 4))
		canPatrol = true
	end
end

local debounce = true

local function Running()
	if target then
		if distance < maxChasingDistance and distance > attackDistance then
			hum.WalkSpeed = 16
			if CheckSight(target) then
				hum:MoveTo(target.HumanoidRootPart.Position)
			else
				PathToTarget(target)
			end
		elseif distance <= attackDistance then
			currentState = "Attacking"
		end
	end
end

local canAttack = true
local function Attacking()
	hum.WalkSpeed = 0
	if canAttack then
		if target then
			local targetHum = target.Humanoid
			if targetHum then
				canAttack = false
				targetHum:TakeDamage(5)
				wait(0.5)
				canAttack = true
			end
		else
			currentState = "Patroling"
		end
	end
	if distance > attackDistance then
		currentState = "Running"
	end
end
-----------

local lastState = nil

-- Logic loop
runService.Heartbeat:Connect(function()
	if target == nil then
		currentState = "Patroling"
		target = FindTarget()
	else
		distance = (target.HumanoidRootPart.Position - root.Position).Magnitude
		if target.Humanoid.Health < 1 or distance > maxChasingDistance then
			target = nil
		end

		if distance < attackDistance + 0.1 then
			currentState = "Attacking"
		end
	end

	if currentState == "Patroling" then
		Patroling()
	elseif currentState == "Running" then
		Running()
	elseif currentState == "Attacking" then
		Attacking()
	end
end)

Also if you wanna try this yourself, just put this script in some character, make sure there are no anchored parts and you are good to go.

And here is a video:

I’ve spent almost 4 hours trying to find the issue but didn’t, and at this point, I have no idea, so any suggestion on what might be the problem would be appreciated.

NVM, I finally solved it. I had to rewrite the whole pathfinding system.