I’m trying to make my dummy’s movement, that I have using Pathfinding Service, to stop stuttering and when a player is near the dummy to target the player instead(targetting a player works perfectly).
After about 1 minute, it goes from perfectly smooth pathfinding to stuttering. When the dummy is chasing a player, it’s fine, but following paths after a minute and it stutters. It’s as if the wait increases drastically between waypoints out of no where.
I’ve found several pages on the devhub all having similar-ish problems but using very different methods. One fix that someone mentioned was runservice.Heartbeat and doing repeat until the dummy is within the waypoints magnitude, but that didn’t solve the issue(maybe somehow I executed that wrong) and even in his video fix it was still moving weird. Another person was using remotes to fire events, and his recommendation was to reduce the amount of times the remote was fired. My dummy is done all serversided so that isn’t something that would be of any use.
local hrp = script.Parent:WaitForChild("HumanoidRootPart")
local dummy = script.Parent
local humanoid = dummy:WaitForChild("Humanoid")
local ii = 0
local function checkforplayer()
if game.Players then
for _, plr in pairs(game.Players:GetChildren()) do
if plr then
if plr.Character then
if plr.Character:FindFirstChild("HumanoidRootPart") then
if plr.Character:FindFirstChild("Humanoid") then
if plr.Character:FindFirstChild("Humanoid").Health > 0 then
local phrp = plr.Character:FindFirstChild("HumanoidRootPart")
if (phrp.Position - hrp.Position).Magnitude < 75 then
return plr.Character
end
end
end
end
end
end
end
end
end
local function path()
local pathfolder = workspace:WaitForChild("PathFolder2")
local pathh = pathfolder:GetChildren()
ii = ii + 1
if ii > #pathh then ii = 1 end
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(hrp.Position,pathh[ii].Position)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for _, waypoint in pairs(waypoints) do
print(waypoint)
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
local char = checkforplayer()
if char ~= nil then print(char) return end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
return
else
warn("didn't work")
end
end
local function movetoplayer(char)
if char then
if char:FindFirstChild("HumanoidRootPart") then
local phrp = char:FindFirstChild("HumanoidRootPart")
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(hrp.Position,phrp.Position)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for _, waypoint in pairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
humanoid:MoveTo(waypoint.Position)
end
end
end
end
end
local function loop()
while wait() do
print("stillgoing")
local playercheck = checkforplayer()
if playercheck ~= nil then print(playercheck, "found")
movetoplayer(playercheck)
else
print(playercheck, "playercheck")
path()
end
end
end
loop()
I’m going to be honest, I made a path finding module for my game that uses similar system but roblox path finding was not working for me. I suggest you just :GoTo then humanoid position if its open field. Just get the closest player and if its far away then rerun the function. Once you get the HumanoidRootPart just say NPC.Hum:MoveTo(HumanoidRootPart.Position)
Or auto generate nodes based off of the terrain. Dont rely on roblox as it is meant for every game as a whole so it might not work in some cases.
Now that I see the video there is really no point to check with all those conditionals as the script us running in the humanoid.
Just simply use the following:
if Char:FindFirstChild("Humanoid") then
local NPC = Char:FindFirstChild("Humanoid")
NPC:MoveTo(Node.Position)
end
I would also use collection service and mark the positions like so
local CS = game:GetServer("CollectionService")
for Index, Nodes in ipairs(CS:GetTagged("Nodes")) do
if Char:FindFirstChild("Humanoid") then
local NPC = Char:FindFirstChild("Humanoid")
NPC:MoveTo(Nodes.Position)
end
end
Thanks for the reply, I figured out the issue. I don’t know why I didn’t think to do this, the issue is still weird and I don’t understand it but the fix is
instead of
if path.Status == Enum.PathStatus.Success then
for _, waypoint in pairs(waypoints) do
print(waypoint)
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
local char = checkforplayer()
if char ~= nil then print(char) return end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
return
else
warn("didn't work")
end
repeat until but without doing runservice
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
for _, waypoint in pairs(waypoints) do
print(waypoint)
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
local char = checkforplayer()
if char ~= nil then print(char) return end
humanoid:MoveTo(waypoint.Position)
repeat
local distance = (waypoint.Position - humanoid.Parent.PrimaryPart.Position).magnitude
wait() until distance <= 5
end
return
else
warn("didn't work")
end
For whatever reason, MoveToFinished:wait() after 1 minute of running slows down dozens of times over between waypoints.
if anyone has any idea why that is please let me know even though it is still working with this method
It is caused by automatic network ownership. Try to set the agent’s network owner to nil (to the server) with this module:
local function setNetworkOwnerOfBasePart(basePart, networkOwner)
local success, errorReason = basePart:CanSetNetworkOwnership()
if success then
basePart:SetNetworkOwner(networkOwner)
else
-- Sometimes this can fail, so throw an error to prevent
-- ... mixed networkownership in the 'model'
error(errorReason)
end
end
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
setNetworkOwnerOfBasePart(descendant, networkOwner)
end
end
end
local function setNetworkOwner(instance, networkOwner)
if instance:IsA("Model") then
setNetworkOwnerOfModel(instance, networkOwner)
elseif instance:IsA("BasePart") then
setNetworkOwnerOfBasePart(instance, networkOwner)
else
warn(instance.Name .. "'s network ownership cannot be modified.")
end
end
return setNetworkOwner