Npc Problems, Please Help

Hi everyone! I have been making pathfinding npcs and for the past week I have been having major problems with them and cannot find no way to fix my problem. So basically the problem that I have been having with them is that when the round starts and the npcs spawn in they don’t move they just stand there. BUT there is a time, normally every 5-10 times I test it that they actually work and move around. So I have been sitting and scratching my head trying to figure this out. I found out that for the times that they do not work that it does not print past the “path created” print. Yet when it works it prints everything. I have been thinking that there is a possibility that this could be a bug with pathfinding but I am not a high enough rank on the forum to post a bug report. But if there is something wrong with my script please help me and tell me what could be causing it.

Here is the main pathfinding script:

local pathfindingservice = game:GetService("PathfindingService")
local lowertorso = script.Parent:WaitForChild("LowerTorso")
local uppertorso = script.Parent:WaitForChild("UpperTorso")
local runservice = game:GetService("RunService")

local human = script.Parent:WaitForChild("Humanoid")
local rootpart = script.Parent:WaitForChild("HumanoidRootPart")
local attackSound = script.Parent.Head:WaitForChild("Attack1")

local attack = script.Parent:WaitForChild("Animation")
local attackanim = human:LoadAnimation(attack)
attackanim.Priority = Enum.AnimationPriority.Action  --action has the highest proiority

local distance = 500
local ignorelist = {}

if script.Parent.HumanoidRootPart:CanSetNetworkOwnership() then
	script.Parent.HumanoidRootPart:SetNetworkOwner(nil)
end


function walkRandomly() --this function makes the npc randomly move when no one is around
	local xrand = math.random(-100, 100)  --this makes it so it picks a random point between -100 studs and 100 studs and makes it move there
	local zrand = math.random(-100, 100)
	local goal  = rootpart.Position + Vector3.new(xrand, 0, zrand)  --adds the random locations together so you can use it for pathfinding

	local path = pathfindingservice:CreatePath() --pathfinding stuff
	path:ComputeAsync(rootpart.Position, goal) 
	local waypoints = path:GetWaypoints()

	if path.Status == Enum.PathStatus.Success then
		for i, waypoint in pairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				human:ChangeState(Enum.HumanoidStateType.Jumping)
			end
			human:MoveTo(waypoint.Position)

			local timeout = human.MoveToFinished:Wait(1) 
			if not timeout then  --if the movetofinished did not wait or work then call the following unstuck function
				print("Got Stuck")
				human:ChangeState(Enum.HumanoidStateType.Jumping)
				if human.Health < 1 then
					break
				end
				main()
			end
		end
	else
		print("Path Failed")
		wait(1)
		walkRandomly()  --if it failed then recall the walkrandomly
	end
end




function findpath(target)--this function makes the path which the npc follows
	local path = game:GetService("PathfindingService"):CreatePath()  --determing the stuff for the path the npc will follow
	path:ComputeAsync(rootpart.Position,target.Position)
		local waypoints = path:GetWaypoints()
print("path created")
	if path.Status == Enum.PathStatus.Success then
print("Path status good")
		for _, waypoint in ipairs(waypoints) do
				if waypoint.Action == Enum.PathWaypointAction.Jump then
					human:ChangeState(Enum.HumanoidStateType.Jumping)
				end
			human:MoveTo(waypoint.Position)
print("Moving to waypoint")
			path.Blocked:Connect(function()
					findpath(target)   --instead of jumping when the path is blocked it is best to recall the findpath function
				end)
				local timeout = human.MoveToFinished:Wait(1)
				if not timeout then  --same as above if it does not do the movetofinished and wait then it redoes the findpath functiona and breaks this function
					human:ChangeState(Enum.HumanoidStateType.Jumping)
					findpath(target)
					break
				end
				if checkSight(target) then  --if the npc sees the target which is defined by a function below
				repeat
print("Moving to target")
						human:MoveTo(target.Position)  --moving the npc to the target
						attackTarget(target)  --attacks the npc using the attack function
						wait(0.1)
						if target == nil then
							break      --all of this checks if the target is true and if not then breaks the repeat loop of the npc moving
						elseif target.Parent == nil then
							break
						end
					until checkSight(target) == false or human.Health < 1 or target.Parent.Humanoid.Health < 1  --stops the repeat function if the target dies or if the npc dies
					break
				end
				if (rootpart.Position - waypoints[1].Position).magnitude > 30 then --if the rootpart - the last waypoint distance is greater than 10 (Besically if the target is far away and moves away then it reloads the path)
					findpath(target)
					break
				end
			end
		end
	end


function checkSight(target)  --This function uses raycasting to check the distance and hieght of the enemy
	local ray = Ray.new(rootpart.Position,(target.Position - rootpart.Position).Unit * 150 )--starts at the root part then shoot to the target from the rootpart and chooses the direction
	table.insert(ignorelist, script.Parent)
	local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, ignorelist) --ignores all parts on the script.Parent
	if hit then  --if it hit something
		if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - rootpart.Position.Y) < 10 then --sees if it relates to the target then checks to see if the hieght is similar to the npcs hieght
			return true
		end
	end
	return false
end

function findTarget()  --this function searches for the target
	local distance = 500
	local target = nil
	local potentialtargets = {}
	local seeTargets = {}

	for i, v in ipairs(game.Workspace:GetChildren()) do
		local humanoid = v:FindFirstChild("Humanoid")
		local humanoidRootPart = v:FindFirstChild("HumanoidRootPart")
		if humanoid and humanoidRootPart and v.Name ~= script.Parent.Name and v.Name ~= "ArmyZombie" and v.Name ~= "BossZombie" and v.Name ~= "BuffZombie" and v.Name ~= "Demon" and v.Name ~= "DoctorZombie" and v.Name ~= "GoldZombie" and v.Name ~= "PoliceZombie" and v.Name ~= "ReaperZombie" and v.Name ~= "RobberZombie" and v.Name ~= "SpeedZombie" and v.Name ~= "SwiperZombie" and v.Name ~= "Zombie" and humanoid.Health > 0 then
			if (rootpart.Position - humanoidRootPart.Position).magnitude < distance then
				table.insert(potentialtargets, humanoidRootPart)  --adds the target that we found into the potential targets table so we can make sure its within range and is a good target
			end
		end
	end

	if #potentialtargets > 0 then --if the number of potential targets is greater than 0 
		for i, v in ipairs(potentialtargets) do  --loops through potential targets
			if checkSight(v) then -- runs the checksight function and sends the potential target to check
				table.insert(seeTargets, v)  --inserts the target into the seetargets
			elseif #seeTargets == 0 and (rootpart.Position - v.Position).magnitude < distance then --if the number if targets seen is equal to 0 and if its not within distance then
				target = v
				distance = (rootpart.Position - v.Position).magnitude

			end
		end
	end
	if #seeTargets > 0 then --if number of targets seen is greater than 0 then
		distance = 500
		for i, v in ipairs(seeTargets) do
			if (rootpart.Position - v.Position).magnitude < distance then
				target = v
				distance = (rootpart.Position - v.Position).magnitude
			end
		end
	end
	if target then
		if math.random(20) == 1 then
			script.Parent.Head.Sound1:Play()
		end
	end
	return target
end

function attackTarget(target)  --this function plays the attack function as well as damages
	if (rootpart.Position - target.Position).magnitude < 2 then
		attackanim:Play()
		attackSound:Play()
		if target.Parent ~= nil then
			target.Parent.Humanoid:TakeDamage(20)
		end
		wait(0.4)
	end
end

local debounce = false
lowertorso.Touched:Connect(function(obj)--this function is if pathfinding messes up
	if debounce == false then
		debounce = true
	if not obj.Parent:FindFirstChild("Humanoid") then
		human:ChangeState(Enum.HumanoidStateType.Jumping)
		end
	end
	wait(1)
	debounce = false
end)


human.Died:Connect(function()
	script:Destroy()
end)

function main() --this  is the function that checks to make sure if its a target and if so then starts the path and if not then makes it walk randomly
	local target = findTarget()
	if target then
		human.WalkSpeed = 22
		findpath(target)
	else
		human.WalkSpeed = 12
		walkRandomly()
	end


end

while wait(0.01) do  --this calls the main function
	if human.Health < 1 then
		break
	end
	main()
end

Here is the spawning script if needed (Also for testing purposes I have it spawning them every so many seconds but normally I have values that make them spawn when a round starts):

while true do
	wait(4)
			local NPC = game.ReplicatedStorage.Zombie:Clone()
			local NPC2 = game.ReplicatedStorage.SpeedZombie:Clone()
			local NPC3 = game.ReplicatedStorage.GoldZombie:Clone()
			local NPC4 = game.ReplicatedStorage.BuffZombie:Clone()
			local NPC5 = game.ReplicatedStorage.ArmyZombie:Clone()
			local NPC6 = game.ReplicatedStorage.Demon:Clone()
			local NPC7 = game.ReplicatedStorage.RobberZombie:Clone()
			local NPC8 = game.ReplicatedStorage.DoctorZombie:Clone()
			local NPC9 = game.ReplicatedStorage.ReaperZombie:Clone()
			local NPC10 = game.ReplicatedStorage.PoliceZombie:Clone()
			local NPC11 = game.ReplicatedStorage.SwiperZombie:Clone()

			local newZombie = math.random(1, 11)
			if newZombie == 1 then
				NPC.Parent = game.Workspace.Map
				NPC.UpperTorso.CFrame = script.Parent.CFrame
			end
			if newZombie == 2 then
				NPC2.Parent = game.Workspace.Map
				NPC2.UpperTorso.CFrame = script.Parent.CFrame
			end
			if newZombie == 3 then
				NPC3.Parent = game.Workspace.Map
				NPC3.UpperTorso.CFrame = script.Parent.CFrame
			end
			if newZombie == 4 then
				NPC4.Parent = game.Workspace.Map
				NPC4.UpperTorso.CFrame = script.Parent.CFrame
			end 
			if newZombie == 5 then
				NPC5.Parent = game.Workspace.Map
		        NPC5.UpperTorso.CFrame = script.Parent.CFrame
			end
			if newZombie == 6 then
				NPC6.Parent = game.Workspace.Map
				NPC6.UpperTorso.CFrame = script.Parent.CFrame
			end
			if newZombie == 7 then
				NPC7.Parent = game.Workspace.Map
				NPC7.UpperTorso.CFrame = script.Parent.CFrame
			end
			if newZombie == 8 then
				NPC8.Parent = game.Workspace.Map
				NPC8.UpperTorso.CFrame = script.Parent.CFrame
			end
			if newZombie == 9 then
				NPC9.Parent = game.Workspace.Map
				NPC9.UpperTorso.CFrame = script.Parent.CFrame
			end
			if newZombie == 10 then
				NPC10.Parent = game.Workspace.Map
				NPC10.UpperTorso.CFrame = script.Parent.CFrame
			end
			if newZombie == 11 then
				NPC11.Parent = game.Workspace.Map
				NPC11.UpperTorso.CFrame = script.Parent.CFrame
	end
		end