I've been trying to make a fix for this for the last 2 days, and that resulted in nothing. This is the script before all of the changes I made to it.
This can be visualized by this
spawn(function() while wait() and game.Players.NumPlayers >= 1 do local ChosenOne = game.Players:GetPlayers()[math.random(1,game.Players.NumPlayers)].Character local PathfindingService = game:GetService("PathfindingService") local pos2 = ChosenOne.Torso.Position local pos1 = script.Parent.Torso.Position local path = PathfindingService:ComputeSmoothPathAsync(pos1, pos2, 500) local points = path:GetPointCoordinates() for i,v in ipairs(points) do print(v) script.Parent.Humanoid:MoveTo(Vector3.new(v.X, pos1.Y, v.Z)) script.Parent.Humanoid.MoveToFinished:wait() end end end)
The script is doing what you have written -- figure out the way to a particular point (where the target was when it started walking), then walk there.
Since that takes time, though, the original path
isn't the path you want to keep following by the time you get there.
The simplest solution is to re-evaluate the path every few seconds and instead follow that path
First, just the following-a-path. You don't need to spawn
your code like you are now.
This will look for path
, a list of Vector3s, and repeatedly walk to the first one, removing it.
local path = {} -- a list of Vector3s while wait() do if #path > 0 then -- There's at least one step on the path local go = table.remove(path, 1) -- Get the first step of the path humanoid:MoveTo(go) humanoid.MoveToFinished:wait() end end
This loops looks just at whatever the first element of path
is -- but it's OK with path
changing entirely. To make it follow more accurately, just swap out path:
local players = game.Players:GetPlayers() local target = player[math.random(#players)] while wait(1) do -- Once a second, update the path (not too often -- this is slow) local from = script.Parent.Torso local to = target.Character.Torso path = PathfindingService:ComputeSmoothPathAsync(from, to, 500) :GetPointCoordinates() end
Just spawn
one of these two so that they can work together.
You said the humanoid would sometimes take a step back and then continue on its way.
I'm guessing that's because it has to "round" its position to the grid, which might be slightly behind it.
Assuming that you don't have extremely tight corners, the solution could be to just remove the first step from the path:
path = PathfindingService:ComputeSmoothPathAsync(from, to, 500) :GetPointCoordinates() table.remove(path, 1)
I'm not exactly sure how the output of ComputeSmoothPathAsync works. It might be necessary to add a check to only remove the first point from path
if that first point is very close (< 4 studs) to the player.