What do you want to achieve? Keep it simple and clear!
A zombie that follows the nearest player using Pathfiding.
What is the issue? Include screenshots / videos if possible!
Finding a way to update the path when the player moves. When the closest player moves, the zombie is still pathfinding to the last position of the player’s PrimaryPart.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I haven’t really tried much since I’m new to Pathfinding.
local pathfindingService = game:GetService("PathfindingService")
local zombie = script.Parent
local humanoid = zombie.Humanoid
local searchRange = 20
local function getClosestPlayer()
local closestDistance, closestPlayer = math.huge, nil
for _, player in pairs(game:GetService("Players"):GetPlayers()) do
if not player.Character or not player.Character.PrimaryPart then
continue
end
local distance = (player.Character.PrimaryPart.Position - zombie.PrimaryPart.Position).Magnitude
if distance <= searchRange and distance < closestDistance then
closestDistance, closestPlayer = distance, player
end
end
return closestPlayer
end
while true do
local player = getClosestPlayer()
if player then
local path = pathfindingService:CreatePath()
path:ComputeAsync(zombie.PrimaryPart.Position, player.Character.PrimaryPart.Position)
for _, waypoint in pairs(path:GetWaypoints()) do
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
end
wait(0.1)
end
the thing here is that the loop only restarts once the zombie went through each node of the path. instead, use a coroutine and stop the one that was running before:
local currentPath
while true do
local player = getClosestPlayer()
if currentPath then
coroutine.yield(currentPath)
end
currentPath = coroutine.resume(coroutine.create(function()
if player then
local path = pathfindingService:CreatePath()
path:ComputeAsync(zombie.PrimaryPart.Position, player.Character.PrimaryPart.Position)
for _, waypoint in pairs(path:GetWaypoints()) do
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
end
end))
wait(0.1)
end
I would try and fix this myself but I haven’t really used coroutine.create, resume, or yield. When I try what you suggested the zombie doesn’t move at all
What I need to do is restart the path every iteration of the while loop, so using yield and creating a new coroutine could work, but I’m not sure why it isn’t yielding
Edit: using prints on the script without the coroutine shows that it doesn’t make a new path until the previous one finishes, so I just need to figure out how to make a new path when it iterates through
Hello! A year passed since the last message in this thread, but I am working on the same Zombie Pathfinding AI right now and have the same issue. The main thing I have understand is that we must avoid
for _, waypoint in pairs (path:GetWaypoints()) do
end
at all costs. Because this is kinda tricky to stop the loop when player’s position has changed. I can recommend to replace this loop with a function that will check current player’s location after a zombie has reached a certain waypoint (or every single waypoint, depends on specifics of your AI). And if the position has changed you restart the loop and recompute the path. Also you need to change your
while true do
to something like
while wait (1) do
because the “while true do” eats a lot more resources. If a big amount of your zombies using this method consider putting the code into a ModuleScript. It will optimize the game and your code.