I'm making an office with NPC employees that walk around. They go from stations, meetings, to the break room, and etc.
When the npc's are first spawned they walk perfectly fine to their next station, but after a set amount of time when they go to their next, they walk super slow and jolty. Very similarly to the NPC in this video: https://i.gyazo.com/4571575e0383753710c1b35ec7bd2df7.mp4
here's the code (all of my npc scripts are regular scripts & not local btw)
local PathfindingService = game:GetService("PathfindingService")
local char = script.Parent.Parent
local RepStorage = game:GetService("ReplicatedStorage")
local hrp = char.HumanoidRootPart
if hrp:CanSetNetworkOwnership() then
hrp:SetNetworkOwner(nil) -- setting the owner to the server
end
local function GoToNexStation ()
wait()
local destination1 = game.Workspace[char.PathFinding.NexStation.Value]
local destination = Vector3.new((destination1.Position.X), (hrp.Position.Y), (destination1.Position.Z))
local waypoints = {}
local currentWaypointIndex = 0
local agentParams = {
["AgentHeight"] = 5,
["AgentRadius"] = 2,
["AgentCanJump"] = true,
["WayPointSpacing"] = 4
}
local path = PathfindingService:CreatePath(agentParams)
local function followPath()
path:ComputeAsync(hrp.Position, destination)
waypoints = {}
if path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
currentWaypointIndex = 1
for i, waypoint in pairs(waypoints) do
if char.Name == "Gale" then
print(currentWaypointIndex, " / ", #waypoints)
end
if waypoints[currentWaypointIndex] ~= nil then
if currentWaypointIndex <= #waypoints then
if waypoints[currentWaypointIndex].Action == Enum.PathWaypointAction.Jump then
char.Humanoid.Jump = true
end
local evt = Instance.new("BindableEvent")
delay(2, function()
if evt then
evt:Fire("Timeout")
end
end)
char.Humanoid.MoveToFinished:Connect(function() if evt then evt:Fire("Finished") end end)
if currentWaypointIndex <= #waypoints then
char.Humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
end
local result = evt.Event:Wait()
evt:Destroy()
evt = nil
if result == "Timeout" then
char.Humanoid.Jump = true
currentWaypointIndex = #waypoints + 1 -- cancel out
GoToNexStation ()
return {status = 0}
end
if currentWaypointIndex == #waypoints then
char.HumanoidRootPart.CFrame = CFrame.new(destination1.Position) * CFrame.Angles(math.rad(destination1.Orientation.X), math.rad(destination1.Orientation.Y), math.rad(destination1.Orientation.Z))
char.PathFinding.CurStation.Value = char.PathFinding.NexStation.Value
end
currentWaypointIndex = currentWaypointIndex + 1
end
end
end
return {status = 1}
else
if char.PathFinding.CurStation.Value ~= char.PathFinding.NexStation.Value then
print("failure")
currentWaypointIndex = #waypoints + 1 -- cancel out
GoToNexStation ()
end
end
end
local function onPathBlocked(blockedWaypointIndex)
print("Blocked")
currentWaypointIndex = #waypoints + 1 -- cancel out
GoToNexStation ()
return
end
From what I've read people have all said its either from spamming :MoveTo in a loop or from Network Ownership
I do have it print each time the player walks to a station or starts a new path, so I'm 99% positive it has nothing to do with spamming :MoveTo.
I also implemented a bunch of returns and ways to stop the script from spamming it.
I've tried setting the network owner in the script I use to spawn them (separate script from above) where I used this code:
local npc = game.Workspace:FindFirstChild("Noob"):Clone()
local function setNetworkOwnerOfModel(model, networkOwner)
for _, descendant in pairs(model:GetDescendants()) do
-- Go through each part of the model
if descendant:IsA("BasePart") then
-- Try to set the network owner
local success, errorReason = descendant:CanSetNetworkOwnership()
if success then
descendant:SetNetworkOwner(networkOwner)
else
-- Sometimes this can fail, so throw an error to prevent
-- ... mixed networkownership in the 'model'
error(errorReason)
end
end
end
end
setNetworkOwnerOfModel(npc, nil)
The odd thing is that it sometimes happens & sometimes doesn't. Although it usually does. I believe it could have something to do with the "blocked" function, or the else statement I put for if the path:ComputeAsync doesn't == success. But I could be wrong and it could be something else. I'm genuinely so confused.
There's a lot of different articles on "NPC pathfinding staggering" but I just can't seem to find a solution that works for me.
I've looked at every article I can find on it on scriptinghelpers and devforum and I just can't seem to fix anything.
