Why does my NPC "limp" when moving between waypoints?

Hey developers! I’ve been scripting a pathfinding script for my NPC, but it doesn’t seem to be functioning properly. The problem is that whenever I walk closely to the NPC, he starts to “limp” between waypoints; and if I walk away from him, he starts walking normally again. I’ve been trying to find a solution here on the DevForum and on the Developer Hub, but couldn’t seem to find anything that would help. Do you guys have any suggestions on how this could be resolved?

Video of the NPC walking normally (running the game, not actually play-testing it):

https://youtu.be/7-bFCAwddzA

Video of the NPC “limping” when my character gets too close:

https://youtu.be/fkaYWiCCXiI

Here is my entire script (code that is commented out isn’t essential to the pathfinding, but I left it in just in case). Any help would be appreciated!

(The script is a ServerScript inside of the NPC itself.)

local PathfindingService = game:GetService("PathfindingService")
--local ServerStorage = game:GetService("ServerStorage")

local humanoid = script.Parent:WaitForChild("Humanoid")
local root = script.Parent:WaitForChild("HumanoidRootPart")

local path = PathfindingService:CreatePath()
local followingPath = false

--local function GenerateParts(waypoints)
--	if #workspace.Waypoints:GetChildren() > 0 then
--		workspace.Waypoints:ClearAllChildren()
--	end
	
--	for _, waypoint in pairs(waypoints) do
--		local point = ServerStorage.Misc.Waypoint:Clone()
--		point.Position = waypoint.Position
--		point.Parent = workspace.Waypoints
--	end
--end

function FollowPath(destination)
	print("Finding new path..")
	
	--followingPath = true
	path:ComputeAsync(root.Position, destination.Position)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		print("Path found, following..")
		
		--if workspace.Configurations.ShowNpcWaypoints.Value == true then
		--	GenerateParts(waypoints)
		--end
		
		for _, waypoint in pairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				humanoid.Jump = true
			end
			
			humanoid:MoveTo(waypoint.Position)
			local timeout = humanoid.MoveToFinished:Wait(1)
			
			if not timeout then
				humanoid.Jump = true
				FollowPath(destination)
				break
			end
		end
		
		--if #workspace.Waypoints:GetChildren() > 0 then
		--	workspace.Waypoints:ClearAllChildren()
		--end
		
		--followingPath = false
	else
		warn("Path not found.")
		humanoid.Jump = true
		FollowPath(destination)
	end
end

--ServerStorage.PathEvents.Dummy.Event:Connect(function(destination)
--	if not followingPath then
--		FollowPath(destination)
--	end
--end)
2 Likes

Try setting the NetworkOwner of the NPC to the server instead of the default which is the game tries to hand off between server/client automatically. When your character gets too close, the game will try to hand off the physics to your client, which can result in the weirdness you’re seeing.

3 Likes

Ah, it worked! Thank you so much :smiley:

So, I looped through the NPC’s descendants and changed their NetworkOwner to nil

for _, descendant in pairs(script.Parent:GetDescendants()) do
    if descendant:IsA("BasePart") then
        descendant:SetNetworkOwner(nil)
    end
end

He now walks normally when I get close to him, thanks again :slight_smile:

1 Like