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

Why does the NPCs start lagging when there is more than one npc?

Asked by
DevingDev 346 Moderation Voter
5 years ago
Edited 5 years ago

Everything is working fine when you play solo on studio but when you upload the game onto Roblox and try it the start starts lagging or something but only when there are two NPCs, the first one works completely fine until there are more than two NPCs.

https://gyazo.com/ede126aa799d1342ecf7e1098087affc

Modulescript:

local AI = {}
AI.__index = AI

local PhysicsService = game:GetService("PhysicsService")
local playerCollisionGroupName = "NPCs"

local PhysicsService = game:GetService("PhysicsService")
local playerCollisionGroupName = "Players"
PhysicsService:CreateCollisionGroup(playerCollisionGroupName)
PhysicsService:CollisionGroupSetCollidable(playerCollisionGroupName, playerCollisionGroupName, false)

local Points = {}
local Last10Points = {}

local function setCollisionGroupRecursive(object)
    if object:IsA("BasePart") then
        PhysicsService:SetPartCollisionGroup(object, playerCollisionGroupName)
    end
    for _, child in ipairs(object:GetChildren()) do
        setCollisionGroupRecursive(child)
    end
end

local function Tablecontains(table, element)
    for i,v in pairs(table) do
        if table == element then
            return true
        end
    end
    return false
end

local function CreatePool(player)
    local AssetsGuest = game.ReplicatedStorage.AssetsGuest
    local IslandGuest = AssetsGuest.IslandGuest:Clone()
    IslandGuest.Parent = workspace.LocalDump
    IslandGuest.Name = "Bob"

    setCollisionGroupRecursive(IslandGuest)

    local SpawnPositions = workspace.Map.Tiles
    local Index = math.random(1, #SpawnPositions:GetChildren())
    local ChosenPoint = SpawnPositions:GetChildren()[Index]

    IslandGuest:SetPrimaryPartCFrame(CFrame.new(ChosenPoint.PrimaryPart.Position) + Vector3.new(0, 5, 0))

    return IslandGuest
end

local WaitForMoveToFinished
do
    local RunService = game:GetService("RunService")    

    function WaitForMoveToFinished(self, position, timeout)
        local initTime = tick()
        timeout = timeout or 1e3

        local position2D = Vector3.new(position.X, self.RootPart.Position.Y, position.Z)

        while ((self.RootPart.Position - position2D).magnitude > 2.5 and tick() - initTime < timeout) do
            RunService.Heartbeat:Wait()
        end
    end
end


function AI:CreatePath()
    local PathFindingService = game:GetService("PathfindingService")

    local Path = PathFindingService:FindPathAsync(self.StartTile.Position, self.TargetDestination.Position)
    local Waypoints = Path:GetWaypoints()

    for i = 2, #Waypoints do
        local lastWaypoint = Waypoints[i - 1]
        local currentWaypoint = Waypoints[i]

        local segment = Instance.new("LineHandleAdornment")
        local lastPosition = lastWaypoint.Position + Vector3.new(0, 0.5, 0) - self.StartTile.Position
        local currentPosition = currentWaypoint.Position + Vector3.new(0, 0.5, 0) - self.StartTile.Position
        local toCurrent = currentPosition - lastPosition
        local distance = toCurrent.Magnitude

        return currentWaypoint.Position
    end
end

function AI:GetTarget()
    if #Last10Points >= 10 then
        Last10Points = {}
    end
    local Index = math.random(1, #Points)

    repeat
        Index = math.random(1, #Points)
        wait()
    until not Tablecontains(Last10Points, Points[Index])

    local Point = Points[Index]
    self.TargetDestination = Point
    self.StartTile = self.RootPart

    if (self.TargetDestination.Position - self.RootPart.Position).magnitude > 40 then
        return self.TargetDestination, Index
    else
        repeat
            Index = math.random(1, #Points)
            wait()
            print("waiting")
        until not Tablecontains(Last10Points, Points[Index])
        print("seccond man choise duuuddee")

        local Point = Points[Index]
        self.TargetDestination = Point
        self.StartTile = self.RootPart

        return self.TargetDestination, Index
    end
end

function AI:New(player)
    local self = {
        Model = CreatePool(player),
--      Name = Name,
        RootPart = nil,
        Humanoid = nil,

        StartTile = nil,
        LastTarget = nil,

        TargetDestination = nil,
        TimeElapsed = tick(),
        TimeUntilDestination = 0,

        STATE_OCCUPIED = 0,
        STATE_QUEUED = 0,
        STATE_WANDERING = 0,
        STATE_IDLE = 0,
    }
    setmetatable(self, AI)

    for i,v in pairs(workspace:GetDescendants()) do
        if v.Name == "Path" then
            if not Tablecontains(Points, v.PrimaryPart) then
                table.insert(Points, v.PrimaryPart)
            end
        end
    end

    self.RootPart = self.Model:FindFirstChild("HumanoidRootPart")
    self.Humanoid = self.Model:FindFirstChild("Humanoid")

    return self
end

function AI:Roam()
    local STATE_OCCUPIED = self.STATE_OCCUPIED
    local STATE_QUEUED = self.STATE_QUEUED
    local STATE_WANDERING = self.STATE_WANDERING
    local STATE_IDLE = self.STATE_IDLE

    local reachedPoint = true

    while (true) do
        if STATE_OCCUPIED == 0 and STATE_QUEUED == 0 and STATE_WANDERING == 0 then
            STATE_WANDERING = 1

            local Target, Index
            if (reachedPoint) then
                Target, Index = self:GetTarget()
                reachedPoint = false
            end

            local Position = self:CreatePath()

            if not Position then
                repeat
                    wait()
                    Position = self:CreatePath()
                until Position
            end

            self.Humanoid:MoveTo(Position)
            --self.Humanoid.MoveToFinished:Wait()

            WaitForMoveToFinished(self, Position, 2)

            if (self.RootPart.Position - self.TargetDestination.Position).magnitude < 10 then
                reachedPoint = true
                table.insert(Last10Points, Points[Index])
            end

            STATE_WANDERING = 0
            if STATE_OCCUPIED == 0 and STATE_QUEUED == 0 and STATE_WANDERING == 0 then
                STATE_IDLE = 1
            end
        end
        wait(0)
    end
end

return AI
0
Probably beceause of the pathfinding being memory consuming ComradeG1Z 31 — 5y

Answer this question