AI makes new paths before even finishing one

I’m trying to make a new and better AI for my horror game, I am following this tutorial by gnomecode
for the AI.

But it creates new paths before even finishes one. Shown here with navigation mesh on.

My code: (no errors)

local Players = game:GetService("Players")
local PathFindingService = game:GetService("PathfindingService")

local wendigo = script.Parent

local VISION_RANGE = 50
local ATTACK_RANGE = 15
local KILL_RANGE = 3.5

local target = nil
local distance = nil

local navigating = false

local path = PathFindingService:CreatePath({
	AgentRadius = 1.5,
	AgentHeight = 5,
	AgentCanJump = false,
	Costs = {
		NoWendigoAllowed = math.huge
	}
})

local function getRandomPath()
	local waypoints = workspace.WendigoWaypoints:GetChildren()
	local randomPoint = waypoints[math.random(#waypoints)]
	
	local success, errorMessage = pcall(function()
		path:ComputeAsync(wendigo.PrimaryPart.Position, randomPoint.Position)
	end)
	
	if success and path.Status == Enum.PathStatus.Success then
		return path:GetWaypoints()
	else
		local reverse = (wendigo.PrimaryPart.CFrame * CFrame.new(0, 0, 3)).Position
		
		wendigo.Humanoid:MoveTo(reverse)
		task.wait(0.1)
		return false
	end
end

local function EndNavigation()
	navigating = false
	
	if destinationReached then
		destinationReached:Disconnect()
	end
end

local function StartNavigation()
	navigating = true

	local waypoints = getRandomPath()
	if not waypoints then
		EndNavigation()
		return
	end

	local waypointIndex = 1

	destinationReached = wendigo.Humanoid.MoveToFinished:Connect(function(reached)
		if reached and waypointIndex < #waypoints then
			waypointIndex += 1
			wendigo.Humanoid:MoveTo(waypoints[waypointIndex].Position)
		else
			EndNavigation()
		end
	end)

	wendigo.Humanoid:MoveTo(waypoints[waypointIndex].Position)
end

local function getTarget()
	local maxDistance = VISION_RANGE
	local newTarget = nil
	
	for i, player in Players:GetPlayers() do
		local character = player.Character
		
		if not character then continue end
		
		local root = character:FindFirstChild("HumanoidRootPart")
		local humanoid = character:FindFirstChild("Humanoid")
		
		if not root or not humanoid or humanoid.Health <= 0 then continue end
		
		local origin = wendigo.PlayerDetection.Position
		local direction = root.Position - origin
		local distance = direction.Magnitude
		
		if distance > VISION_RANGE then continue end
		
		if distance > ATTACK_RANGE then
			local fov = direction.Unit:Dot(wendigo.Head.CFrame.LookVector)
			
			if fov < 0.5 then continue end
		end
		
		local result = workspace:Raycast(origin, direction * VISION_RANGE)
		
		if not result or not result.Instance then continue end
		
		if not result.Instance:FindFirstAncestor(character.Name) then continue end
		
		if distance < maxDistance then
			maxDistance = distance
			newTarget = character
		end
	end
	
	return newTarget, maxDistance
end

task.spawn(function()
	while wendigo do
		target, distance = getTarget()

		wendigo.PrimaryPart:SetNetworkOwner(nil)

		navigating = false

		if target then
			EndNavigation()
			wendigo.Humanoid:MoveTo(target.PrimaryPart.Position)
			if distance < KILL_RANGE then
				target.Humanoid.Health = 0
			end
		elseif not navigating then
			StartNavigation()
		end

		task.wait()
	end
	
	EndNavigation()
end)
1 Like

The problem lies within the StartNavigatioon() function. You see, you’re connecting to the event of the humanoid MoveToFinished, which is creating a new thread. What you should do is loop through the waypoints and use wendigo.Humanoid.MoveToFinished:Wait() so that the function finishes after the entire path has been navigated.

tysm! the tutorial i was using was for a doors game so it used multiple threads and was used originally in a modulescript but not made for a single monster like mine.