Path finding NPC works slowly

I’m just making a NPC chase :slight_smile: , but path finding is working very slow :frowning: I tried making it in local script but I don’t think that this will help…

There are 2 chases. In the first one ( The first chase that the script starts running ), the NPC is moving pretty normal :slight_smile: , but in the 2nd chase, the NPC is moving slow even if the walk speed value is 20 and the player’s one is 21, and the walk animation is glitching…

Here is the script

-- local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local chasing = false
local lastPlayer = nil

local path = game.PathfindingService:CreatePath({
	AgentHeight = 6;
	AgentRadius = 2;
	AgentCanJump = true;
	
	Costs = {
		Water = 100;
		DangerZone = math.huge
	}
})

local function FindNearestPlayerPerson(myRootPArt, dir, players)
	local nearestRootPart = nil
	local player = nil
	for i, v in pairs(players) do
		local otherRootPart = v:FindFirstChild('HumanoidRootPart')
		if otherRootPart then
			local dirToCurrentPerson = (otherRootPart.Position - myRootPArt.Position).Magnitude
			if dirToCurrentPerson < dir and dirToCurrentPerson > 0  then
				dir = (otherRootPart.Position - myRootPArt.Position).Magnitude
				nearestRootPart = otherRootPart
				player = v
			end
		end
	end
	return nearestRootPart, player, dir
end

local function chaseTarget(target, dir)
	local deb = false
	print('Chase started') -- THE CHASE STARTS FROM HERE
	repeat
		local function InSight()
			local ignore = { script.Parent.HumanoidRootPart.Parent }
			local vecRootPart = target.Position - script.Parent.HumanoidRootPart.Position
			local ray = Ray.new(script.Parent.HumanoidRootPart.Position, vecRootPart.Unit * dir)
			local hit, position = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
			if hit then
				if hit:IsDescendantOf(target.Parent) then
					return true
				else
					return false
				end
			end
		end
		
		local inSightVal = InSight()
		if inSightVal == false then
			if deb == false then
				deb = true
				
				spawn(function()
					print('Not in sight') -- CHECKING IF PLAYER IS NOT IN SIGHT
					wait(3)
					if InSight() == false then
						chasing = false
						print('Chase ended') -- THE CHASE ENDS HERE
						return
					end
					deb = false
				end)
				
			end
		end
		
		local succes, errorMessage = pcall(function()
			path:ComputeAsync(script.Parent.HumanoidRootPart.Position, target.Position)
		end)

		if succes and path.Status == Enum.PathStatus.Success then
			waypoints = path:GetWaypoints()

			blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
				if blockedWaypointIndex >= nextWaypointIndex then
					blockedConnection:Disconnect()
					chaseTarget(target, dir)
				end
			end)

			if not reachedConnection then
				reachedConnection = script.Parent.Humanoid.MoveToFinished:Connect(function(reached)
					if reached and nextWaypointIndex < #waypoints then
						nextWaypointIndex += 1
						script.Parent.Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
					else
						reachedConnection:Disconnect()
						blockedConnection:Disconnect()
					end
				end)
			end

			nextWaypointIndex = 2
			script.Parent.Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
		else
			warn(errorMessage)
		end
		wait()
	until chasing == false
end

local function RayCast(myRootPart, dir, speed)
	local hum = myRootPart.Parent.Humanoid
	hum.WalkSpeed = speed
	local ignore = { myRootPart.Parent }
	local players = {}
	
	for i, v in pairs(game.Players:GetChildren()) do
		if v.Character then
			if v.Character:FindFirstChild('HumanoidRootPart') then
				local rootPart = v.Character.HumanoidRootPart
				local vecRootPart = rootPart.Position - myRootPart.Position
				local ray = Ray.new(myRootPart.Position, vecRootPart.Unit * dir)
				local hit, position = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
				if hit then
					if hit:IsDescendantOf(rootPart.Parent) then
						table.insert(players, v.Character)
					end
				end
			end
		end
	end
	
	if players then
		local rootPart, player = FindNearestPlayerPerson(script.Parent.HumanoidRootPart, dir, players)
		if rootPart == nil or player == nil then
			return
		end

		if lastPlayer ~= player then
			chasing = false
		end

		if chasing == false then
			chasing = true
			lastPlayer = player
			spawn(function()
				chaseTarget(rootPart, dir)
			end)
		end
	end
end

while wait() do
	RayCast(script.Parent.HumanoidRootPart, 300, 20)
end

I wrote prints in the script!

Any help appreciated! :slight_smile: And if u didn’t understand, tell me…

1 Like

script.Parent.HumanoidRootPart:SetNetworkOwner(nil)

1 Like

Do I must to loop this? Or just put it at the start of the script?

Here’s an explanation on why you might want to call :SetNetworkOwner(nil) Weird Npc Movement Animations With PathFindingService - #3 by CompilerError

For @Beloathed 's response you only need to set it once, probably somewhere near the top of your script.

1 Like

After testing the game when script.Parent.HumanoidRootPart:SetNetworkOwner(nil) was in loop or under the variables at start of the script, it worked with both solutions. I want to thank you both so much for taking attention and helping me! :heart:

1 Like

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