AI sometimes doesn't detect player

I have a script inside of a model which wanders until it detects a player, but while its wandering sometimes it doesn’t detect the player.

Script:

local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")
local lowerTorso = script.Parent:WaitForChild("Torso")

local grab = script.Parent:WaitForChild("Grab")
local grabAnim = myHuman:LoadAnimation(grab)
grabAnim.Priority = Enum.AnimationPriority.Action

local grabSound = head:WaitForChild("Attack")
local screamSound = head:WaitForChild("Scream")

local clone = script.Parent:Clone()

function walkRandomly()
	local xRand = math.random(-50,50)
	local zRand = math.random(-50,50)
	local goal = myRoot.Position + Vector3.new(xRand,0,zRand)
	
	local path = game:GetService("PathfindingService"):CreatePath({
		Costs = {
			Wall = math.huge
		}
	})
	path:ComputeAsync(myRoot.Position, goal)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				myHuman.Jump = true
			end
			myHuman:MoveTo(waypoint.Position)
			local timeOut = myHuman.MoveToFinished:Wait(1)
			if not timeOut then
				print("Got stuck")
				myHuman.Jump = true
				walkRandomly()
			end
		end
	else
		print("Path failed")
		wait(1)
		walkRandomly()
	end
end

function findPath(target)
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position,target.Position)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				myHuman.Jump = true
			end
			myHuman:MoveTo(waypoint.Position)
			local timeOut = myHuman.MoveToFinished:Wait(1)
			if not timeOut then
				myHuman.Jump = true
				print("Path too long!")
				findPath(target)
				break
			end
			if checkSight(target) then
				repeat
					print("Moving directly to the target")
					myHuman:MoveTo(target.Position)
					attack(target)
					wait(0.1)
					if target == nil then
						break
					elseif target.Parent == nil then
						break
					end
				until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
				break
			end
			if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
				print("Target has moved, generating new path")
				findPath(target)
				break
			end
		end
	end
end

function checkSight(target)
	local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
	local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
	if hit then
		if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
			print("I can see the target")
			return true
		end
	end
	return false
end

function findTarget()
	local dist = 50
	local target = nil
	local potentialTargets = {}
	local seeTargets = {}
	for i,v in ipairs(workspace:GetChildren()) do
		local human = v:FindFirstChild("Humanoid")
		local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
		if human and torso and v.Name ~= script.Parent.Name then
			if (myRoot.Position - torso.Position).magnitude < dist and human.Health > 0 then
				table.insert(potentialTargets,torso)
			end
		end
	end
	if #potentialTargets > 0 then
		for i,v in ipairs(potentialTargets) do
			if checkSight(v) then
				table.insert(seeTargets, v)
			elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
				target = v
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	if #seeTargets > 0 then
		dist = 200
		for i,v in ipairs(seeTargets) do
			if (myRoot.Position - v.Position).magnitude < dist then
				target = v
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	if target then
		if math.random(20) == 1 then
			screamSound:Play()
		end
	end
	return target
end

function attack(target)
	if (myRoot.Position - target.Position).magnitude < 5 then
		grabAnim:Play()
		grabSound:Play()
		if target.Parent ~= nil then
			target.Parent.Humanoid:TakeDamage(25)
		end
		wait(0.4)
	end
end

function died()
	wait(5)
	clone.Parent = workspace
	game:GetService("Debris"):AddItem(script.Parent,0.1)
end

myHuman.Died:Connect(died)

lowerTorso.Touched:Connect(function(obj)
	if not obj.Parent:FindFirstChild("Humanoid") then
		myHuman.Jump = true
	end
end)

function main()
	local target = findTarget()
	if target then
		myHuman.WalkSpeed = 32
		findPath(target)
	else
		myHuman.WalkSpeed = 22
		walkRandomly()
	end
end

while wait(0.1) do
	if myHuman.Health < 1 then
		break
	end
	main()
end





Time it detects the player:
robloxapp-20221113-2200359.wmv (1.5 MB)

Time it doesn’t detect the player:
robloxapp-20221113-2157028.wmv (2.5 MB)

If the player is further than 50 studs away then it will never find the player.

In the video I am not 50 studs away, I was like 5 studs away.

Do you know at what point in the script the code is breaking? (Since you already have prints in place)

Im pretty sure it breaks here

Some times it also breaks here

You can use the prints to see which sections of the code are and are not firing, and I’m guessing that you mean that the “Got stuck” and “Path too long!” prints aren’t firing.

My guess as to what’s happening is as follows:
The :Wait(1) does not timeout a couple lines before the "Got stuck" print. There are no parameters available for the RBXScriptSignal:Wait() method and it yields until the condition is met. As a solution to this, you could use the RBXScriptSignal:Once() method and store the returned RBXScriptConnection to be disconnected after a timeout period.

Here’s an example of putting this to use:

local eventConnection = myHuman.MoveToFinished:Once(function()
	--bla bla
	print("Move finished!")
end)
task.delay(1,function()
	--Timeout!
	if eventConnection then
		eventConnection:Disconnect()
	end
end)

Obviously, I think you’d want to alter this code (and I think I wrote it with the backwards purpose of what you were using it for) but the general structure could still be used.

The script is from the advanced zombie AI YellowMustang video (just a bit edited), this is probably because this script is not meant to be used at custom bodies. (like the backroom monster thing i saw at the “time it doesnt detect the player” thing)

I could modify it for the backroom monster right? Its also rigged pretty weirdly it came only with a torso.I added a humanoidrootpart, humanoid, and a head, it moves around, just doesn’t sometimes.

Alright, thanks for the help! Im going to try this right away!

Sadly i dont know, but i think you gotta have some knowledge of roblox Ai to modify it and it work.

What is rawblockzz ai? Is it a ai someone made?

nah its just a dumb joke i made, i thought u would get it

gtg bye (epicrapbattlesofhistory)

Where would I add this and what would I replace it with? Im guessing here

Yeah, there and the other place where it’s breaking.

I am still confused where to put this, I’m not that good at scripting AI this is my first time.

The lines that look like this:

local timeOut = myHuman.MoveToFinished:Wait(1)
if not timeOut then
	print("Got stuck")
	myHuman.Jump = true
	walkRandomly()
end```

Do I just add it or do I have to remove some parts, sorry, im really not that good at scripting and have never used :Once before.