Enemy AI ignores players after teleporting

Recently I’ve been working on a backrooms themed game where the exit of each level teleports you to the next one by changing the primary part’s CFrame via :SetPrimaryPartCFrame(). Problem is, after teleporting to any level with NPCs that are supposed to chase you, these just simply ignore you and continue wandering around. I’ve tried changing the AI, searching on the dev forum, yet nothing seems to work.

Currently the NPCs use a slightly modified version of Y3llow Mustang’s Zombie AI, which I’ll leave here:

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

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 moanSound = head:WaitForChild("Moan")

local clone = script.Parent:Clone()

function walkRandomly()
	local xRand = math.random(-20,20)
	local zRand = math.random(-20,20)
	local goal = myRoot.Position + Vector3.new(xRand,0,zRand)
	
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position, goal)
	local waypoints = path:GetWaypoints()
	
	if math.random(20) == 1 then
		moanSound:Play()
	end
	
	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in pairs(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
				walkRandomly()
			end
		end
	else
		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 pairs(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
				findPath(target)
				break
			end
			if checkSight(target) then
				repeat
					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
				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
			return true
		end
	end
	return false
end

function findTarget()
	local dist = 50
	local target = nil
	local potentialTargets = {}
	local seeTargets = {}
	for i,v in pairs(workspace:GetChildren()) do
		local human = v:FindFirstChildOfClass("Humanoid")
		local torso = v:FindFirstChild("UpperTorso")
		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 pairs(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 pairs(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()
	print(target)
	if target then
		myHuman.WalkSpeed = 10
		findPath(target)
	else
		myHuman.WalkSpeed = 7
		walkRandomly()
	end
end

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

Thanks in advance for any help I may recieve!

Is it because its not firing the function findTarget()?

It is running it, but it constantly returns nil.

Sorry for the bump, but could anyone please take a look at the script?
Been trying several things to fix it, including briefly disabling and re-enabling the AI, but nothing seems to work…

can you show the script you are using for the teleport?

It’s inside a proximity prompt

local TweenService = game:GetService("TweenService")
local Exits = {}

for i,v in pairs(workspace:GetChildren()) do
	if v.Name == "Level1Entrance" then
		table.insert(Exits,v)
	end
end

script.Parent.Triggered:Connect(function(plr)
	local Tween = TweenService:Create(plr.PlayerGui.MainGUI.BlackScreen,TweenInfo.new(2),{BackgroundTransparency = 0}):Play()
	wait(2)
	local Teleporter = Exits[math.random(1, #Exits)]
	plr.Character:SetPrimaryPartCFrame(Teleporter.SpawnPlace.CFrame)
	wait(2)
	local Tween = TweenService:Create(plr.PlayerGui.MainGUI.BlackScreen,TweenInfo.new(2),{BackgroundTransparency = 1}):Play()
	for i,v in pairs(workspace:GetDescendants()) do
		if v.Name == "AI" and v:IsA("Script") then
			v.Disabled = true
			delay(0.1,function()
				v.Disabled = false
			end)
		end
	end
end)

ok, going back to the findTarget function, have you put any print statements in the loop to see if it is even detecting any players in the workspace? And have it print the distance, to see what distance they are. Only do this for the npc’s in the room that they are ignoring you.

They do detect the players and print them, they just won’t go after them.

i will try to put that ai script into an npc, and do a teleport with your teleport script, and I will see if I can get it to not chase me

Okay, hope you can help to get it work.
Thank you so much!

how far are you spawning, because its working when I go from this room to that

also… at the end of your spawn script, I see you disable all the AI, then re-enable them? I don’t see the reason for doing this.

Try this for the AI, see if it makes any difference… ALSO remove from your spawn script, the part where it Disable, and Enable the AI scripts.

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

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 moanSound = head:WaitForChild("Moan")

local clone = script.Parent:Clone()

function walkRandomly()
	local xRand = math.random(-20,20)
	local zRand = math.random(-20,20)
	local goal = myRoot.Position + Vector3.new(xRand,0,zRand)

	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position, goal)
	local waypoints = path:GetWaypoints()

	if math.random(20) == 1 then
		moanSound:Play()
	end

	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in pairs(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
			end
		end
	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 pairs(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
				return
			end
			if checkSight(target) then
				repeat
					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
				return
			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
			return true
		end
	end
	return false
end

function findTarget()
	local dist = 50
	local target = nil
	local potentialTargets = {}
	local seeTargets = {}
	for i,v in pairs(game.Players:GetPlayers()) do
		if v and v.Character and v.Character:FindFirstChild("Humanoid") then
			local human = v.Character.Humanoid
			local hrp = v.Character.PrimaryPart
			if (myRoot.Position - hrp.Position).magnitude < dist and human.Health > 0 then
				table.insert(potentialTargets,hrp)
			end
		end
	end
	if #potentialTargets > 0 then
		for i,v in pairs(potentialTargets) do
			if checkSight(v) then
				table.insert(seeTargets, v)

			end
		end
	end
	if #seeTargets > 0 then
		dist = 200
		for i,v in pairs(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()
	print(target)
	if target then
		myHuman.WalkSpeed = 10
		findPath(target)
	else
		myHuman.WalkSpeed = 7
		walkRandomly()
	end
end

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

Thanks, I’ll try this now.
The reason for disabling and re-enabling the AI was that it seemed to work while testing on Studio, but testing on Player didn’t work.

Hmmm… That didn’t seem to work, even tried disabling StreamingEnabled since the player teleports from a pretty large distance (from the yellow square to the gray one, dummies on the middle baseplate for comparison):