So for some reason, when you make the character’s speed higher(or change the speed mid movement) it does this weird pausing thing?
The activate just makes the npc activate an ability that lasts for 3 seconds, making the walkspeed 25.
local CS = game:GetService("CollectionService")
local Pathfind = game:GetService("PathfindingService")
local attacktag = "Prey"
function isprey(part)
return CS:HasTag(part, attacktag)
end
while task.wait(0.1) do
local human = script.Parent.Humanoid
local pos = human.RootPart.Position
local target = nil
local targetDistance = math.huge
local path = Pathfind:CreatePath({["WaypointSpacing"] = 32})
local op = OverlapParams.new()
op.FilterType = Enum.RaycastFilterType.Exclude
op.FilterDescendantsInstances = {script.Parent}
for _, i in workspace:GetPartBoundsInRadius(pos, 1000, op) do
if isprey(i) then
if (i.Position-pos).Magnitude < targetDistance then
path:ComputeAsync(pos, i.Position)
if path.Status == Enum.PathStatus.Success then
target = i.Position
targetDistance = (i.Position-pos).Magnitude
end
end
end
end
if target then
path:ComputeAsync(pos, target)
local waypoint = path:GetWaypoints()[2]
human:MoveTo(waypoint.Position)
end
end
I believe this is because the zombie is getting your position on the server, which is a bit delayed, making the script think the zombie is touching you, it “pauses” because of the collisions of your character, it’s pretty much like walking into a wall. I’m not sure this is the reason why though.
You can try to look on the server side how it looks like (click on the Test tab and click on Start on the “Clients and Servers” section".
Actually, I think it’s because you’re only using one of the computed waypoints, meaning that it has to constantly wait for a new computation before moving again.
You should change it to go through all waypoints and refresh them in the background.
Alternatively you could also make it blindly move towards your target while it’s computing a path.
They do that when they reach the waypoint and then hit a pause before the next waypoint is known or if the pause overlaps. It’s all about the timing vs your spacing.
Nice tight little NPC script. I wonder what a task.wait(0.033) would do here vs 0.1 …
I’d sure mess around with that number a bit as close as this is now.
Looks like it’s stopping to attack…
I actually thought that was a task.wait(1) … 0.1 should be good.
I just know that is a fine balance to get that not to pause like that.
The ones I made took a lot of playing around to find the right balance.
Hey, the pausing happens because you’re recalculating the path way too often and not handling the waypoints properly. You’re calling ComputeAsync multiple times per loop, which basically makes the NPC stop and rethink its route constantly. Also, you’re trying to move to a whole list of waypoints at once instead of going through them one by one.
Here’s a cleaner way to do it: find your target first, compute the path once, then move through each waypoint in order, waiting until the NPC reaches each point before moving on. That should stop the pausing.
Check this out:
local CS = game:GetService("CollectionService")
local PathfindingService = game:GetService("PathfindingService")
local attackTag = "Prey"
local humanoid = script.Parent.Humanoid
local rootPart = humanoid.RootPart
function isPrey(part)
return CS:HasTag(part, attackTag)
end
while task.wait(0.1) do
local position = rootPart.Position
local target = nil
local closestDistance = math.huge
local overlapParams = OverlapParams.new()
overlapParams.FilterType = Enum.RaycastFilterType.Exclude
overlapParams.FilterDescendantsInstances = {script.Parent}
for _, part in workspace:GetPartBoundsInRadius(position, 1000, overlapParams) do
if isPrey(part) then
local dist = (part.Position - position).Magnitude
if dist < closestDistance then
target = part.Position
closestDistance = dist
end
end
end
if target then
local path = PathfindingService:CreatePath({WaypointSpacing = 32})
path:ComputeAsync(position, target)
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
for _, waypoint in ipairs(waypoints) do
humanoid:MoveTo(waypoint.Position)
local reached = humanoid.MoveToFinished:Wait()
if not reached then
break -- stop if path is blocked
end
end
end
end
end
Try that and see if it smooths things out. If you’re still stuck, maybe rethink how often you’re changing walk speed or interrupting movement.
I tried to set the npc’s baseparts network owner to the player too and use your script but it didn’t work.
The only lead I have is the fact it’s on a different position in the server but network owner is the only thing that solves that and even that didn’t work. I don’t interrupt movement at all, what’s going on.
i had a NPC system of mine that fixes this a long time ago, like everyone said already, it’s already reached to the target and the server already sees that but it happens cuz it’s also looking at the client side pos of the target, no matter if u set network owner to nil, it’ll still happen occasionally until you stopped
one of the naïve solution was to, add velocity of where the target is moving, this works but, it could be far or that even if it was already reaching the target by 2 studs, you can also dodge them easily by zig-zagging so it can’t rlly catch
what i did was basically using RemoteFunctions that return the actual client position instead of server by invoking the pos of the target, the difference is that now NPC will be able to catch the character, though a side note here while Remote functions aren’t typically recommended cuz of how exploitable it is, someone already made another function that uses remote event, works the same way as remote functions but rn the way it works is kind of a troublemaker
here’s after i applied the second fix ignore the hitbox miss, i swapped to magnitude and it managed to hit me
pathfinding at close range is always choppy and unnecessary
at close range, you should make a raycast to the player character and pathfind if its blocked, otherwise just call :MoveTo directly to the character position
If the NPC is on a different position on the server and you’re trying to set network ownership to a player, that won’t fix pathfinding pauses caused by server-side movement logic. Network ownership mainly affects physics simulation and client-side prediction, but pathfinding and Humanoid:MoveTo run on the server.
Make sure your pathfinding and movement code runs only on the server and that the NPC’s position is consistent there. If the NPC’s position is out of sync between server and client, that can cause weird movement behavior.
Also, check if any other scripts or constraints are affecting the NPC’s Humanoid or RootPart movement. Sometimes collisions, anchored parts, or conflicting scripts cause pauses.
If you want, try adding debug prints to confirm the NPC’s position and path status on the server each step, and verify that MoveToFinished events are firing as expected.