Pathfinding only works on 1 NPC

i’ve moved pathfinding to server script service, to a module script and a server script

works smoothly, but it caps out at 1 enemy and i don’t really know why

if 1 enemy follows you, nobody else can

module script

local pfService = game:GetService("PathfindingService")


local pathfinding = {}

function pathfinding.melee(Humanoid, targetPosition)
	if not Humanoid then return end		
	if not targetPosition then return end

	local pathParameters = {
		AgentRadius = 2,
		AgentHeight = 2,
		AgentCanJump = true,
		AgentCanClimb = false
	}

	local path = pfService:CreatePath(pathParameters)
	local humanoidRootPart = Humanoid.Parent:FindFirstChild("HumanoidRootPart")

	local startPosition = humanoidRootPart.Position


	local success, errorMessage = pcall(function()
		path:ComputeAsync(startPosition, targetPosition)
	end)

	if not success then
		warn("Pathfinding failed: " .. errorMessage)
		return
	end

	local waypoints = path:GetWaypoints()

	if path.Status == Enum.PathStatus.Success and #waypoints > 0 then
		for i = 2, #waypoints do
			local waypoint = waypoints[i]

			if waypoint.Action == Enum.PathWaypointAction.Jump then
				Humanoid.Jump = true
			end

			Humanoid:MoveTo(waypoint.Position)
			local moveFinished = Humanoid.MoveToFinished:Wait()
		end    
		return path
	end    
end

return pathfinding

server script

local enemyInfo = require(game:GetService("ServerScriptService"):WaitForChild("Enemies").EnemyStats)
local pathfindingModule = require(game:GetService("ServerScriptService"):WaitForChild("Enemies").PathfindingModule)

local runService = game:GetService("RunService")
local enemiesFolder = workspace:WaitForChild("Enemies")

local heartbeatConnection

heartbeatConnection = runService.Heartbeat:Connect(function()
	if #enemiesFolder:GetChildren() > 0 then
		local enemies = enemiesFolder:GetChildren()

		for _, enemy in ipairs(enemies) do
			if enemy.EnemyType.Value == "MELEE" then
				local detectionBox = enemy:FindFirstChild("DetectionPart")
				local humanoid = enemy:FindFirstChildOfClass("Humanoid")


				local closestPlayer = nil
				local LOS = workspace:GetPartBoundsInBox(detectionBox.CFrame, detectionBox.Size)

				for _, v in pairs(LOS) do
					if v.Parent:FindFirstChild("Humanoid") then
						local targetPlayer = game.Players:GetPlayerFromCharacter(v.Parent)

						if targetPlayer then
							if closestPlayer == nil or (enemy.HumanoidRootPart.Position - targetPlayer.Character.HumanoidRootPart.Position).Magnitude < (enemy.HumanoidRootPart.Position - closestPlayer.Character.HumanoidRootPart.Position).Magnitude then
								closestPlayer = targetPlayer
							end
						end
					end
				end

				if closestPlayer then
					local targetPosition = closestPlayer.Character.HumanoidRootPart.Position
					pathfindingModule.melee(humanoid, targetPosition)
				else
					humanoid:MoveTo(enemy.HumanoidRootPart.Position)
				end
			end
		end
	else
		heartbeatConnection:Disconnect()
	end
end)
3 Likes

Can you check if your .Heartbeat loop iterate through all enemies?

1 Like

printing enemies does give out 2 enemies, there are only 2 enemies on the map so it does iterate :^)

1 Like

I tried to replicate your code using your code and putting each enemy’s move function into its own thread solves the issue, and also makes it stop lagging – I’m not sure if that’s also a problem you’re having

This:

To this:

spawn(function()
	if closestPlayer then
		local targetPosition = closestPlayer.Character.HumanoidRootPart.Position
		pathfindingModule.melee(humanoid, targetPosition)
	else
		humanoid:MoveTo(enemy.HumanoidRootPart.Position)
	end
end)

I’m not entirely sure if spawn() is the best option for separating the threads, but it works.

3 Likes

haven’t experienced any lagging before, nor now

but it does indeed work, thanks!

2 Likes

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