I am working on a zombie pathfinding script that's meant to update itself to move to the nearest player. The path works great, but the zombies wait until the end of the path to update, instead of after every 2 seconds. I tried using bools and value.Changed events to alert the function when it should stop its path and update itself, but it doesn't seem to work. What do I do?
local zombie = script.Parent local hrp = zombie.PrimaryPart local hum = zombie.Humanoid local values = zombie.Values local mode = zombie.ZombieMode local plrFolder = workspace:WaitForChild("InGamePlayers") local foundPlr = false local nearestPlr = nil local nearestDist = nil local pathActive = false local cutPath = false function findNearestPlayer() for i,v in pairs(workspace:GetChildren()) do -- searching for players if game.Players:FindFirstChild(v.Name) and v:FindFirstChild("HumanoidRootPart") ~= nil then local dist = (v.PrimaryPart.Position - zombie.PrimaryPart.Position).Magnitude if nearestDist == nil or nearestDist > dist and v.Humanoid.Health > 0 then nearestDist = dist nearestPlr = v end end end if nearestPlr then followPath(nearestPlr) end end function followPath(target) zombie.Paths:ClearAllChildren() local targetHrp = target:FindFirstChild("HumanoidRootPart") local path = game:GetService("PathfindingService"):FindPathAsync(hrp.Position,targetHrp.Position) local points = path:GetWaypoints() local partColor = Color3.fromHSV(math.random(),1,1) for i,v in pairs(points) do local p = Instance.new("Part") p.Parent = zombie.Paths p.Anchored = true p.CanCollide = false p.Shape = Enum.PartType.Ball p.TopSurface = Enum.SurfaceType.Smooth p.CFrame = CFrame.new(v.Position) p.Size = Vector3.new(1,1,1) p.Color = partColor end if path.Status == Enum.PathStatus.NoPath then print("there's no path! oh no") return nil end if path.Status == Enum.PathStatus.Success then for i,v in pairs(points) do if cutPath then print("new path was called. Destroying current path.") cutPath = false return nil end if targetHrp == nil then print("no primary part") return nil end hum:MoveTo(v.Position) hum.MoveToFinished:wait() if v.Action == Enum.PathWaypointAction.Jump then hum.Jump = true end end end end if mode.Value == "Default" then while wait(3) do cutPath = true findNearestPlayer() end end
You would have to put a break in the loop that controls the movement of a humanoid. Putting a break in the loop allows for it to generate a new path. In this example, the path recalcs every other point it walks to.
local zombie = script.Parent local hrp = zombie.PrimaryPart local hum = zombie.Humanoid local values = zombie.Values local mode = zombie.ZombieMode local plrFolder = workspace:WaitForChild("InGamePlayers") local foundPlr = false local nearestPlr = nil local dist = nil local pathActive = false local cutPath = false function findNearestPlayer() dist = 9e9 nearestPlr = nil for k, plr in pairs(game:GetService("Players"):GetPlayers()) do if nil ~= plr.Character then local human = plr.Character:FindFirstChildWhichIsA("Humanoid", true) if nil ~= human then if human.Health > 0 then local ndist = plr:DistanceFromCharacter(zombie.PrimaryPart.Position) if dist > ndist then dist, nearestPlr = ndist, plr end end end end if nil ~= plr then if nil ~= plr.Character then followPath(plr.Character) end end end end function followPath(target) zombie.Paths:ClearAllChildren() local targetHrp = target:FindFirstChild("HumanoidRootPart") local path = game:GetService("PathfindingService"):FindPathAsync(hrp.Position, targetHrp.Position) local points = path:GetWaypoints() local partColor = Color3.fromHSV(math.random(), 1, 1) for i,v in pairs(points) do local p = Instance.new("Part") p.Parent = zombie.Paths p.Anchored = true p.CanCollide = false p.Shape = Enum.PartType.Ball p.TopSurface = Enum.SurfaceType.Smooth p.CFrame = CFrame.new(v.Position) p.Size = Vector3.new(1,1,1) p.Color = partColor end if path.Status == Enum.PathStatus.NoPath then return print("there's no path! oh no") end if path.Status == Enum.PathStatus.Success then for i,v in pairs(points) do if cutPath then cutPath = false return print("new path was called. Destroying current path.") end if targetHrp == nil then print("no primary part") return nil end hum:MoveTo(v.Position) hum.MoveToFinished:wait() if v.Action == Enum.PathWaypointAction.Jump then hum.Jump = true else hum.Jump = false end if i > 1 then break -- Add a break to recalc path end end end end if mode.Value == "Default" then while wait(3) do cutPath = true findNearestPlayer() end end
Note:You may want to change your while loop to a shorter duration.