Ai raycast doesn't seem to be working properly

I’m currently working on an Ai script, which recognizes the player, but the chase state unravels quickly and doesn’t recognize the player very well despite the wide viewing angle. Can someone help me fix this script?

local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local teddy = script.Parent
local humanoid = teddy.Humanoid
local folder = workspace:WaitForChild('waypoint')
local paths = 1
local nameForPath = "Part"
local maxPath = 10
local chasing = false

-- Load the animations into AnimationTracks
local runAnim = humanoid:LoadAnimation(script:WaitForChild("RunAnim"))
local walkAnim = humanoid:LoadAnimation(script:WaitForChild("WalkAnim"))

wait(2)
teddy.PrimaryPart:SetNetworkOwner(nil)


local function canSeeTarget(target)
	local origin = teddy.HumanoidRootPart.Position - Vector3.new(0, 2, 0) -- 약간 아래에서 시작
	local targetPosition = target.HumanoidRootPart.Position

	-- 기본 방향 (정면)
	local directions = {
		(targetPosition - origin).unit, 
		CFrame.Angles(0, math.rad(45), 0):VectorToWorldSpace((targetPosition - origin).unit), -- 오른쪽 45도
		CFrame.Angles(0, math.rad(-45), 0):VectorToWorldSpace((targetPosition - origin).unit), -- 왼쪽 45도
	}

	local ignoreList = {teddy}
	for _, direction in pairs(directions) do
		local ray = Ray.new(origin, direction * 180)
		local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)

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

	return false
end

local function findTarget()
	local players = game.Players:GetPlayers()
	local maxDistance = 200
	local nearestTarget
	for index, 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 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
					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
				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 getPath(destination)
	local pathfindingService = game:GetService("PathfindingService")
	local path = pathfindingService:CreatePath({
		AgentRadius = 2,
		AgentHeight = 5,
		AgentCanJump = true,
		AgentMaxSlope = 45,
		AgentJumpHeight = 10,
		AgentMaxDistance = 100,
	})
	path:ComputeAsync(teddy.HumanoidRootPart.Position, destination.Position)
	return path
end

local function walkTo(destination)
	local path = getPath(destination)
	if path.Status == Enum.PathStatus.Success then
		local waypoints = path:GetWaypoints()

		for index, 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
				humanoid:MoveTo(waypoint.Position)
				humanoid.MoveToFinished:Wait(2)
				chasing = false
				script.Parent.Chasing.Value = false
				updateMovementAnim(chasing)  -- 애니메이션 즉시 업데이트
			end
		end
	else
		local waypointsFolder = workspace:WaitForChild('waypoint')
		local waypoints = waypointsFolder:GetChildren()
		local randomWaypoint = waypoints[math.random(1, #waypoints)]
		teddy:SetPrimaryPartCFrame(CFrame.new(randomWaypoint.Position))
		wait(0.5)
		-- 경로를 다시 계산
		local repath = getPath(destination)
		if repath.Status == Enum.PathStatus.Success then
			local waypoints = repath:GetWaypoints()

			for index, 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
					humanoid:MoveTo(waypoint.Position)
					humanoid.MoveToFinished:Wait(2)
					chasing = false
					script.Parent.Chasing.Value = false
					updateMovementAnim(chasing)  -- 애니메이션 즉시 업데이트
				end
			end
		end
	end
end

function updateMovementAnim(isChasing)
	local velocity = teddy.PrimaryPart.Velocity.Magnitude

	-- 속도를 isChasing 상태에 따라 변경
	if isChasing then
		humanoid.WalkSpeed = 60  -- 추격 중일 때 속도
		if not runAnim.IsPlaying then
			runAnim:Play()
		end
		if walkAnim.IsPlaying then
			walkAnim:Stop()
		end
	else
		humanoid.WalkSpeed = 30  -- 추격 중이 아닐 때 속도
		if velocity >= 39 then
			if walkAnim.IsPlaying then
				walkAnim:Stop()
			end
			if not runAnim.IsPlaying then
				runAnim:Play()
			end
		else
			if runAnim.IsPlaying then
				runAnim:Stop()
			end
			if not walkAnim.IsPlaying then
				walkAnim:Play()
			end
		end
	end
end

function patrol()
	local goal

	if chasing == false then
		if paths ~= maxPath then
			paths = paths + 1
			goal = workspace:WaitForChild('waypoint')[nameForPath..paths]
		else
			paths = 1
			goal = workspace:WaitForChild('waypoint')[nameForPath..paths]
		end
	else
		goal = workspace:WaitForChild('waypoint')[nameForPath..paths]
	end

	walkTo(goal)

end



while wait() do
	patrol()
	updateMovementAnim(chasing)
end