Help with pathfinding Ai

hello, I have a Pathfinding Ai script and there’s a problem with it, whenever a Player is getting chased by the Ai and the Ai looses sight of the player, the Ai turns away but then goes back to chasing the player. I need it where the Ai doesn’t jerk away after a player turns a corner then goes back to the chase the player, it shouldn’t do that. Any Help?

local Dummy = script.Parent
local Humanoid = Dummy.Humanoid
local IsPatrolling = true
Dummy.PrimaryPart:SetNetworkOwner(nil)

-- // Pathfinding variables \\--
local Rand = Random.new()
local Waypoints = workspace.Area.Waypoints:GetChildren()
local RaycastLength = 70
local AutoDetectRadius = 20
local PlayersInSafeRoom = require(script.SafeRoomHandler)

local PathfindingService = game:GetService("PathfindingService")
local PathParams = {
	["AgentHeight"] = 9,
	["AgentRadius"] = 6,
	["AgentCanJump"] = false
}

local LastTarget
local HasTarget = false
local LastSeen


-- // Raycast Param \\ --
local RaycastParam = RaycastParams.new()
RaycastParam.FilterDescendantsInstances = {Dummy}
RaycastParam.FilterType = Enum.RaycastFilterType.Blacklist

local function CanSeeTarget(Target)
	local origin = Dummy.PrimaryPart.Position
	local direction = (Target.PrimaryPart.Position - Dummy.PrimaryPart.Position)
	
	
	-- If player is in not safe room
	if not table.find(PlayersInSafeRoom, Target) then
		-- Cast ray to check walls
		
		local RaycastResult = workspace:Raycast(origin, direction + direction.Unit, RaycastParam)

		if RaycastResult then
			-- Hit something!
			local Hit = RaycastResult.Instance

			if Hit:IsDescendantOf(Target) then
				-- No walls in between player and dummy, check if they're in front or near the player
				if Dummy.PrimaryPart.CFrame.LookVector:Dot(direction) > 0 or direction.Magnitude < AutoDetectRadius then
					-- Can see player!
					
					return true
				end
			end
		end
	end
	
	return false
end

local function FindTarget()
	local Players = game:GetService("Players"):GetPlayers()
	local MaxDistance = math.huge
	local Nearest = nil
	
	-- Get nearest player
	for _, Player in pairs(Players) do
		local Character = Player.Character
		
		if Character then
			if Character.Humanoid.Health > 0 then
				local Distance = (Dummy.PrimaryPart.Position - Character.PrimaryPart.Position).Magnitude
				
				if Distance < MaxDistance and CanSeeTarget(Character) then
					Nearest = Character
					MaxDistance = Distance
				end
			end
		end
	end
	
	-- Check if it found a player
	if Nearest then
		HasTarget = true
		LastTarget = Nearest
		LastSeen = os.time()
		
		return Nearest
	else
		--Check if it has found a player before
		if LastTarget then
			if os.time() - LastSeen < 4 then
				-- Hasn't been 4s
				
				return LastTarget
			end
		end
		
		-- No players
		
		LastTarget = nil
		HasTarget = false
		return nil
	end
end

local function MoveTo(Destination, IsAttacking)
	local Path = PathfindingService:CreatePath(PathParams)
	Path:ComputeAsync(Dummy.PrimaryPart.Position, Destination.Position)
	
	if Path.Status == Enum.PathStatus.Success then
		for _, Waypoint in pairs(Path:GetWaypoints()) do
			if HasTarget and not IsAttacking then
				-- Stop when a target is found and only patrolling

				return
			end
			
			-- Automatically break when he sees you again
			if IsAttacking then
				if CanSeeTarget(Destination.Parent) then
					break
				end
			end
			
			Humanoid:MoveTo(Waypoint.Position)
			Humanoid.MoveToFinished:Wait()
		end
	end
end

local function Patrol()
	if IsPatrolling then
		local r = Rand:NextInteger(1, #Waypoints)
		local Waypoint = Waypoints[r]
		
		if not HasTarget then
			MoveTo(Waypoint)
		else
			task.wait()
		end
		
		-- No need for infinite loops
		Patrol()
	end
end

local function Attack(Target)
	local Distance = (Dummy.PrimaryPart.Position - Target.PrimaryPart.Position).Magnitude

	if Distance > 2 then
		if CanSeeTarget(Target) then
			Humanoid:MoveTo(Target.PrimaryPart.Position)
		else
			MoveTo(Target.PrimaryPart, true)
			
			-- Lose Target if he can't see you anymore
			
			if not CanSeeTarget(Target) then
				LastTarget = nil
			end
		end
	else
		Target.Humanoid.Health = 0
		HasTarget = false
		LastTarget = nil
	end
end

local StartTargetting = coroutine.wrap(function()
	while IsPatrolling do
		local Target = FindTarget()
		
		if Target then
			Attack(Target)
		end
		
		task.wait()
	end
end)

StartTargetting()
Patrol()

1 Like

Try to make it so that the ai skips the first waypoint as for whatever reason ComputeAsync() makes a waypoint behind the ai, if that doesn’t work, just use FindPathAsync(), it’s the only solution that worked for me.