Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Too many Pathfinding Npc's causing lag, what could fix this?

Asked by 2 years ago

I'm trying to make a zombie wave type of game inspired by COD but I have been stuck on a lag problem when npc's pathfind. When there's one zombie pathfinding, it works well, but the more Zombies there are pathfinding, the more they lag and start to break.

Any ideas on fixing or optimizing this problem?

I'm currently using one script to control all zombies in a folder in the Workspace.

local Debris = game:GetService("Debris")

function followplayer(zombie)
    local players = game.Players:GetPlayers()

    -- Get nearest player --

    local nearestPlayer = nil
    local nearestMag = math.huge

    if not zombie then
        return
    end

    for i, player in pairs(players) do
        if zombie:FindFirstChild("HumanoidRootPart") == nil then
            return
        end

        local playerCharacter = workspace:WaitForChild(player.Name)
        local magnitude = (playerCharacter.HumanoidRootPart.Position - zombie.HumanoidRootPart.Position).Magnitude
        zombie.HumanoidRootPart:SetNetworkOwner(nil)

        if magnitude < nearestMag then
            nearestMag = magnitude
            nearestPlayer = playerCharacter
        end
    end

    -- Check if that nearest player exists, then pathfind to that player --

    if nearestPlayer ~= nil and zombie then
        local pathfindingService = game:GetService("PathfindingService")
        local path = pathfindingService:CreatePath()
        path:ComputeAsync(zombie.HumanoidRootPart.Position, nearestPlayer.HumanoidRootPart.Position)

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

            for i, waypoint in pairs(waypoints) do
                if zombie:FindFirstChild("HumanoidRootPart") then
                    zombie.Humanoid:MoveTo(waypoint.Position)
                    zombie.Humanoid.MoveToFinished:Wait()
                end
            end
        else
            if zombie:FindFirstChild("HumanoidRootPart") then
                zombie.Humanoid:MoveTo(nearestPlayer.HumanoidRootPart.Position)
            end
        end
    else
        return
    end

    if zombie:FindFirstChild("HumanoidRootPart") then
        local magnitude = (nearestPlayer.HumanoidRootPart.Position - zombie.HumanoidRootPart.Position).Magnitude

        if magnitude < 5 and not zombie:FindFirstChild("Debounce") then
            local debounce = Instance.new("BoolValue", zombie)
            debounce.Name = "Debounce"
            nearestPlayer.Humanoid:TakeDamage(20)

            Debris:AddItem(debounce, 0.8)
        end
    end
end

local zombies = game.Workspace.ZombieFolder:GetChildren()

for i, zombie in pairs(zombies) do
    game:GetService("RunService").Heartbeat:connect(function()
        followplayer(zombie)
    end)
end

game.Workspace.ZombieFolder.ChildAdded:connect(function(zombie)
    game:GetService("RunService").Heartbeat:connect(function()
        followplayer(zombie)
    end)
end)

Any help would be great!

Answer this question