I'm having an issue with AI pathfinding in my game

More specifically, I want to fix a structural problem in my script. Right now, the AI is set up to simply walk in a straight line toward the target, which causes many issues when chasing a player. The current structure only allows direct movement and doesn’t utilize proper pathfinding.

I would like to use pathfinding when chasing a target, but the detection needs to happen during the WalkTo process, so it’s hard to move the logic outside the function.

How can I properly use pathfinding when the AI is chasing a moving target like a player?

local function canSeeTarget(target)
	local origin = teddy.HumanoidRootPart.Position
	local direction = (target.HumanoidRootPart.Position - teddy.HumanoidRootPart.Position).unit * 150
	local ignoreList = {teddy}
	local ray = Ray.new(origin, direction)
	local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)

	if hit then
		if hit:IsDescendantOf(target) then
			if game.Players:GetPlayerFromCharacter(target) and not game.Players:GetPlayerFromCharacter(target).Invincible.Value then
				return true
			end
		end
	end
	return false
end

local function findTarget()
	local players = game.Players:GetPlayers()
	local maxDistance = 1200
	local nearestTarget

	for _, player in pairs(players) do
		if player.Character then
			local target = player.Character
			if target and target:FindFirstChild("HumanoidRootPart") then
				local distance = (teddy.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
				if isTeddyAlive == false then
					game.Players:GetPlayerFromCharacter(target).IsChasing.Value = false
					game.Players:GetPlayerFromCharacter(target).GettingChasedBy.Value = nil
					return
				end
				if distance < maxDistance and canSeeTarget(target) then
					if target.Humanoid.Health > 0 then
						nearestTarget = target
						maxDistance = distance
						game.Players:GetPlayerFromCharacter(target).IsChasing.Value = true
						game.Players:GetPlayerFromCharacter(target).GettingChasedBy.Value = script.Parent
					end
				else
					if game.Players:GetPlayerFromCharacter(target).GettingChasedBy.Value == script.Parent then
						game.Players:GetPlayerFromCharacter(target).IsChasing.Value = false
						game.Players:GetPlayerFromCharacter(target).GettingChasedBy.Value = nil
					end
				end
			end
		end
	end
	return nearestTarget
end

local function walkTo(destination)
	local path = PathfindingService:CreatePath({
		AgentHeight = 15,
		AgentRadius = 4,
		AgentCanJump = false
	})
	path:ComputeAsync(teddy.HumanoidRootPart.Position, destination.Position)

	if path.Status == Enum.PathStatus.Success then
		local waypoints = path:GetWaypoints()
		for _, waypoint in pairs(waypoints) do
			local target = findTarget()
			if target and target.Humanoid.Health > 0 then
				humanoid:MoveTo(target.HumanoidRootPart.Position)
				chasing = true
				script.Parent.Chasing.Value = true
			else
				if waypoint.Action == Enum.PathWaypointAction.Jump then
					humanoid.Jump = true
				end
				humanoid:MoveTo(waypoint.Position)
				humanoid.MoveToFinished:Wait(2)
				chasing = false
				script.Parent.Chasing.Value = false
				updateMovementAnim(chasing)
			end
		end
	end
end
function patrol()
	local goal
	if chasing == false then
		if paths ~= maxPath then
			paths = paths + 1
			goal = waypointsFolder[nameForPath..paths]
		else
			paths = 1
			goal = waypointsFolder[nameForPath..paths]
		end
	else
		goal = waypointsFolder[nameForPath..paths]
	end
	walkTo(goal)
	checkForAttack()
end

while wait(0.1) do
	if not isTeddyAlive then
		stopAllActions()
		break
	end
	patrol()
	updateMovementAnim(chasing)
end 
1 Like