Npc Humanoid:MoveToFinished is delayed

Hello, i hope you all are having a good day.

So my issue is, i have npcs which chase players down, but the hum:moveto is heavily delayed.

I have used this script to set the npc’s network owner to nil:


module.SetNetworkOwner = function(Character)
	for i,v in pairs(Character:GetDescendants()) do
		
		if v:IsA("Part") or v:IsA("BasePart") then
			
			v.Massless = true
			v.CollisionGroup = "Players"
			
			pcall(function()
				if v.Anchored == false then
				   v:SetNetworkOwner(nil)
				end
			end)
			
			
		end
	end
end

it is functioning, from what i can tell, since all the npcs are highlighted in white, when i turn on “are owners shown”.

the pathfinding script:


local module = {}

local PathfindingService = game:GetService("PathfindingService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local TweeenService = game:GetService("TweenService")

local Both = ReplicatedStorage:WaitForChild("Modules"):WaitForChild("Both")
local StatusHandler = require(Both:WaitForChild("StatusHandler"))
local Utilities = require(Both:WaitForChild("Utilities"))
local Pathfinding = require(script.Parent.Parent)

local Raycastparams = RaycastParams.new()
Raycastparams.FilterType = Enum.RaycastFilterType.Include
Raycastparams.FilterDescendantsInstances = {workspace.Map}

local CheckFloor = Utilities.CheckFloor
local CheckLocation = Utilities.CheckLocation
local SetNetworkOwenr = Utilities.SetNetworkOwner
local Distance = Utilities.Distance

local CreatePath = Pathfinding.CreatePath


local Info = TweenInfo.new(0.2,Enum.EasingStyle.Sine,Enum.EasingDirection.Out,0,false,0)

local Players = workspace:WaitForChild("Players")
local Enemies = workspace:WaitForChild("Enemies")

local abs = math.abs
local huge = math.huge

local StraightIncrement = 1

-- Functions


local Types = {}

for i,v in pairs(script:GetChildren()) do

	if v:IsA("ModuleScript") then
		Types[v.Name] = require(v)
    end

end




module.Setup = function(Character,Type)
	
	

    local Hrt = Character:WaitForChild("HumanoidRootPart")
    local Head = Character:WaitForChild("Head")
    local Hum = Character:WaitForChild("Humanoid")
	local Animator = Hum:WaitForChild("Animator")
	
	

	local FindPath
	
	local Radius = Hrt.Size.X + 0.5

    local Path = PathfindingService:CreatePath(
        {AgentRadius = Radius, AgentHeight = 5,AgentCanJump = true,AgentCanClimb = true,WaypointSpacing = 3}
	)
	
	spawn(function()
		while task.wait(1.75) do
			SetNetworkOwenr(Character)
			end
	end)

	
	local Items = Pathfinding.Create(Character)
	
	local CurrentTarget = Items.CurrentTarget
	local Targetting = Items.Targetting
	local IsAttacking = Items.IsAttacking
	
	-- Vars

    local Blocked = nil
    local Reached = nil
    local Changed = nil

    local Waypoints = nil

    local Died = false

    local Find

    local WhiteListFind = {}
    local NewPath = nil
    local Whitelist = {}
    local AutoJump = false
    
    local TargetWhitelist = {}
    local Range = 0
    
	local FollowPath = nil
	local Waypoints = nil
	local Destination = nil
	local LastReached = os.clock()
	local NextIndex = 1
    
    local SF = Character:WaitForChild("SF")
    local StatsFolder = SF:WaitForChild("Stats")
    
    local WhitelistFolder = StatsFolder:WaitForChild("Whitelist")
    TargetWhitelist = WhitelistFolder:GetChildren()
    
    Range = StatsFolder.Range.Value
    

    local AttackMod = Types[Type]
    
    
    local TargetClose = function(PrimaryFind)
        local PrimaryFindPos = PrimaryFind.Position
        local Headpos = PrimaryFind.Parent.Head.Position
        local CharHeadPos = Head.Position

        local Dir = (Headpos - CharHeadPos)
        local Unit = Dir.Unit
        local Dis = Dir.Magnitude

        local NewRay = workspace:Raycast(CharHeadPos,Unit * Dis, Raycastparams)

        local YNitude = abs(PrimaryFindPos.Y - Hrt.Position.Y)
        local Jp = Hum.JumpPower^2 / (2*workspace.Gravity)

        local CeiledDis = math.ceil(Dis / StraightIncrement)

        local Positions = {
            [1] = {Position = Hrt.Position},
        }
        
        
        for i = 2,math.clamp(CeiledDis,2,9999) do
            local Mp = math.min(StraightIncrement * i,Dis)
            
            local NewWaypointPos = CharHeadPos + (Unit * Mp )
            --print(i,NewWaypointPos)
            Positions[i] = {Position =  NewWaypointPos}

        end


        if NewRay == nil and YNitude < Jp then
            FollowPath({Destination = Find,AutoJump = true,Waypoints = Positions})
            return true
        end
    end -- does a direct path, if target is visible, instead of pathfinding.
    
    
    local WallRayJump = function()
        local Offset = 1
        
		for i = 1,4 do
			
        local HrtPos = Hrt.CFrame * CFrame.new(0,Offset,0)
        Offset -= 0.5
        
        local Dir = HrtPos.Position - (HrtPos * CFrame.new(0,0,-1)).Position

        local Raycast = workspace:Raycast(Hrt.Position,-Dir.Unit * Dir.Magnitude,Raycastparams)
        
        if Raycast then
            if CheckFloor(Hrt) then
                Hum:ChangeState(Enum.HumanoidStateType.Jumping)
            end
        end
    end
    end
    
	local CheckWhitelist = function(Object)
		
	     

        if Object:FindFirstChild("Tags") == nil then print("notag") return false end
        for i,v in ipairs(TargetWhitelist) do
            if Object.Tags:FindFirstChild(v.Name) then
                return true
            end
        end

        return false

    end

	local FindPlayer = function(Character)
		
		local Hrt = Character:FindFirstChild("HumanoidRootPart")
		if Character == nil or Hrt == nil then return end
		
        local Hrt = Character.HumanoidRootPart
        local Closest = nil
        local ToLoop = Players:GetChildren()


        local Length = 0

        for i,v in pairs(Whitelist) do
            Length += 1
        end

        if Length >= #ToLoop then Whitelist = {} end


        for i,v in pairs(Enemies:GetChildren()) do
            table.insert(ToLoop,v)
        end


        for i,v in pairs(ToLoop) do
            task.wait()
            if v == Character or CheckWhitelist(v)  then continue end

            if v:FindFirstChild("Humanoid") == nil then continue end

            if v.Humanoid.Health <= 0 then continue end

            if Closest == nil and Whitelist[v] == nil then
                Closest = v
            elseif Closest then
                
                local VRoot = v:FindFirstChild("HumanoidRootPart")
                local ClosestRoot = Closest:FindFirstChild("HumanoidRootPart")
                
                
                if not VRoot or not ClosestRoot then continue end
                local Dis1 = (Hrt.Position - VRoot.Position).Magnitude
                local Dis2 = (Hrt.Position - ClosestRoot.Position).Magnitude

                if Dis1 < Dis2 and Whitelist[v] == nil  then
                    Closest = v
                end

            end
        end

        return Closest

    end


    spawn(function()
        if AttackMod then
			spawn(function()
				if AttackMod == nil or AttackMod.Setup == nil then warn(Character.Name .. "Not a valid setup") end
                AttackMod.Setup(Character)
            end)
        end
    end)

	function FollowPath(Args)
		
		Destination = Args.Destination
        Waypoints = Args.Waypoints
        AutoJump = Args.AutoJump
        
        WallRayJump() -- jumps if blocked by wall

       

        if Destination == nil then return end
        if Destination:FindFirstChild("SF") == nil then return end


		local Pos1  = Hrt.Position 
		
		local DestinationRoot = Destination.HumanoidRootPart
		local Pos2 =  DestinationRoot.Position

        local WhiteListFind = {}

        local NewDistance = Distance(Pos1,Pos2)



        --Waypoints = createpath(Destination,Hrt,Hum,Range,Path)

        local CurrentState = Hum:GetState()

		if Waypoints == nil then task.wait(2) FindPath() return end
		
		

		if CurrentState == Enum.HumanoidStateType.Climbing and os.clock() - LastReached <= 6.5 then task.wait(0.1) return end
		
		--[[
		if Waypoints ~= "Continue"  then
			for i,v in pairs(Waypoints) do

				local Part = Instance.new("Part")
				Part.Anchored = true
				Part.Size = Vector3.new(0.5,0.5,0.5)
				Part.CanCollide = false
				Part.Transparency = 0.1
				Part.Position = v.Position
				Part.Parent = workspace.Effects

				task.delay(0.5,function()
					Part:Destroy()
				end)

			end
		end]]
        
        WallRayJump() -- jumps if blocked by wall

		CurrentTarget.Value = Destination
		
		if not Blocked then
        Blocked = Path.Blocked:Connect(function(BlockedIndex)
            if BlockedIndex >= NextIndex then
				FindPath()
				print("Blocked")
            end
        end)
        end
        
        

        local LastPos = DestinationRoot.Position
        local DtAdd = 0
        
        
        
        if not Changed then

			Changed = RunService.Heartbeat:Connect(function(dt)
				
				
				local PrimaryFind
				local CurrentValue = CurrentTarget.Value


				if os.clock() - LastReached >= 1.1 then
					LastReached = os.clock()
					FindPath()
					return
				end -- if not moved, since 0.8 seconds then recalculate path, if blocked will try to jump, as stated in the wallrayjump func

				if CurrentTarget.Value then
					
					PrimaryFind = CurrentValue:FindFirstChild("HumanoidRootPart")
				else
					return
				end -- if therei s a target
				
				if PrimaryFind == nil then return end
				
				local PrimaryFindPos = PrimaryFind.Position
				
				if not IsAttacking.Value and Targetting.Value then


					if CheckFloor(Hrt) then
						local HrtPos = Hrt.Position
						local Pos = CFrame.lookAt(HrtPos,Vector3.new(PrimaryFindPos.X,HrtPos.Y,PrimaryFindPos.Z))
						local Track = TweeenService:Create(Hrt,Info,{CFrame = Pos})
						Track:Play()
					else
						Targetting.Value = false
						IsAttacking.Value = false
					end
				end -- look at enemy if attacking, and not reloading
                
                DtAdd += dt
                if DtAdd < 0.2 then return end -- only checks every 0.2 seconds
                DtAdd = 0
                

                
                
                WhiteListFind = {}

                
                local Distance = (Hrt.Position - LastPos).Magnitude


                if AutoJump then
                    WallRayJump()
                end -- jumps if collided with anything, which is decentdant of workspace.map



                local FindClose = TargetClose(PrimaryFind) -- check the func
                if FindClose then return end



                WhiteListFind = {}
				Find = FindPlayer(Character,WhiteListFind)
				

				if Find and Find ~= CurrentValue then

                    FindPath()

                end


				if CurrentValue then

					if CurrentValue.Humanoid.Health <= 0 then CurrentValue = nil end


					if PrimaryFindPos ~= LastPos and (PrimaryFindPos - LastPos).Magnitude >= 10 then
						FindPath()
                    end

                end -- if currenttarget dies, or if they move 10 studs, will recalculate, enem and or path
                
                
                

                LastPos = PrimaryFindPos

            end)
        end


		if not Reached then
			Reached = Hum.MoveToFinished:Connect(function(reached)
				if Waypoints == nil then return end
                if CurrentTarget.Value == nil then  FindPath() return end
				
                local Pos1  = Hrt.Position 
                local Pos2 =  DestinationRoot.Position


				local WaypointDex = Waypoints[NextIndex]
				
				if WaypointDex == nil then FindPath() return end
                
			   -- print(Distance(Pos1,Pos2) < Range)
			   
				if not CheckLocation(Pos1,Pos2) and Distance(Pos1,Pos2) < Range then return end
				

                if reached and NextIndex < #Waypoints then
                    NextIndex += 1



					LastReached = os.clock()
					
					local Next = Waypoints[NextIndex]
					Hum:MoveTo(Next.Position)
					
					
					if Next.Action == Enum.PathWaypointAction.Jump then
                        if CheckFloor(Hrt) then
                        Hum:ChangeState(Enum.HumanoidStateType.Jumping)
                        end
                    end

                    Targetting.Value = false

                else
                    FindPath()

                end
            end)

        end -- for when it reaches a new waypoint

		NextIndex = 2 -- 1 is the starting pos
		
		
        if Waypoints[NextIndex] then

            local Pos1  = Hrt.Position 
			local Pos2 =  DestinationRoot.Position
			

			
			if CheckLocation(Pos1,Pos2) or Distance(Pos1,Pos2) >= Range then
				

                if Waypoints[NextIndex].Action == Enum.PathWaypointAction.Jump then
                    if CheckFloor(Hrt) then
                        Hum:ChangeState(Enum.HumanoidStateType.Jumping)
                        end
                end

				LastReached = os.clock()
                Hum:MoveTo(Waypoints[NextIndex].Position)


				Targetting.Value = false
            end
        end -- starts the inital pathfinding loop.

    end

    FindPath = function()
        WhiteListFind = {}
        
        repeat
            Find = FindPlayer(Character,WhiteListFind)
            
            if Find then

                local PrimaryFind =  Find:FindFirstChild("HumanoidRootPart")
                
                if PrimaryFind == nil then continue end
                
                local FindClose = TargetClose(PrimaryFind)
                if FindClose then return end

                NewPath = CreatePath(PrimaryFind,Hrt,Hum,Range,Path)

                    FollowPath({Destination = Find,Waypoints = NewPath})
                    
                if NewPath == nil then
                    if Find then
                    WhiteListFind[Find] = true
                    end
                end



            end
            task.wait()
        until  CurrentTarget.Value and NewPath
        
        
        WhiteListFind = {}

    end

    FindPath()

    -- attack


    spawn(function()
        while task.wait() do


            if Died then
                break
            end


            if CurrentTarget.Value == nil then
                FindPath()
            end

        end


    end)

    -- Died
    Hum:GetPropertyChangedSignal("Health"):Connect(function()
        if Hum.Health <= 0 then

            if Changed then
                Changed:Disconnect()
            end

            if Blocked then
                Blocked:Disconnect()
            end

            if Reached then
                Reached:Disconnect()
			end
			
			Path:Destroy()

            Died = true

        end
    end)

end

return module


the networkownerscript force runs every 3 seconds on the npc (maybe it shouldn’t)
this issue mainly happens when i spawn right next to them??

This issue mainly seems to happen when i spawn right next to the npcs. thanks for any responses!

1 Like

yeah, and the issue seems to resolve itself, when i move outof network range.

1 Like

seems to happen when i spawn right next to the npcs??? what is this bug??

1 Like

seems to fix itself, when i set the Humanoidrootpart:networkowner to nil, instead of everything.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.