Zombie Pathfinding Moving the wrong direction

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I would like to make a zombie which follows the closest player(endlessly, until death), while avoiding any new obstacles that show up.

  2. What is the issue? Include screenshots / videos if possible!
    The zombie takes off on a path of it’s own (same spot every time) regardless of where I am.

Video:

External Media
  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I’ve checked several devforums, as well as go on the RCS Discord server for help.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local PFS = game:GetService('PathfindingService')
local RS = game:GetService('RunService')

local path = PFS:CreatePath()
local waypoints = nil

local character = script.Parent

local humanoid = character:WaitForChild('Humanoid')
local animator = humanoid:WaitForChild('Animator')

local hrp = character:WaitForChild('HumanoidRootPart')

local closestCharacter
local closestCharacterHRP

local gameOpened = false
local animPlaying = false

local anim = script.Walk
local l = animator:LoadAnimation(anim)

local function makeWaypoint(wayPos)
	local part = Instance.new("Part")
	part.Size = Vector3.new(1,1,1)
	part.Position = wayPos
	part.CanCollide = false
	part.Anchored = true
	part.Parent = workspace
end

local function findPath(newHRP)
	local success, em = pcall(function()
		path:ComputeAsync(hrp.Position, newHRP.Position)
	end)
	
	if success or path.Status == Enum.PathStatus.Success then
		return true
	else
		findPath(newHRP)
	end
end

local function findPlayer()
	if #game:GetService('Players'):GetChildren() < 1 then return end

	local player = game:GetService('Players'):FindFirstChildOfClass("Player")
	closestCharacter = player.Character or player.CharacterAdded:Wait()

	if not closestCharacter then return end

	for _, player in ipairs(game:GetService('Players'):GetChildren()) do
		local currentCharacter = player.Character or player.CharacterAdded:Wait()

		if ((currentCharacter:WaitForChild('HumanoidRootPart').Position - hrp.Position).Magnitude < (closestCharacter:WaitForChild('HumanoidRootPart').Position - hrp.Position).Magnitude) then
			closestCharacter = currentCharacter
		end
	end

	closestCharacterHRP = closestCharacter:WaitForChild('HumanoidRootPart')
	
	local foundPath = findPath(closestCharacterHRP)
	return foundPath
end

local function moveZombie()
	waypoints = path:GetWaypoints()
	
	for w, waypoint in ipairs(waypoints) do
		local foundaPath = findPlayer()
		
		if foundaPath then
			makeWaypoint(waypoint.Position)
			
			print("reached waypoint")

			humanoid:MoveTo(waypoint.Position)
			humanoid.MoveToFinished:Wait()

			local animLoaded = animator:LoadAnimation(anim)
			if not animLoaded.IsPlaying and not animPlaying then
				animLoaded:Play()
				animPlaying = true
			end
		else
			findPlayer()
		end
	end
end

game:GetService('Players').PlayerAdded:Connect(function(player)
	local character = player.Character or player.CharacterAdded:Wait()

	local successful = findPlayer()
	if not successful then return end
	moveZombie()
end)
1 Like

In your script, you run path:GetWaypoints() before you run path:ComputeAsync(). Because of that, the waypoints will just be some default direction.

The function containing :GetWaypoints() will always run after the function containing :ComputeAsync(), so I don’t believe that’s the issue.

In the code above, I run the findPlayer() function before the moveZombie() function in every scenario where I run the 2.