Better way to create line system?

Hello. I have created a script for my Roblox game where NPCs move in a line for an upcoming cashier system I’m about to create. The way I made the NPCs move was by making a folder with parts numbered 1-5, and the NPC moves to the parts based on their index in a table. Would this be the best way to move the NPCs(I’m mostly concerned if there is a better way than using a repeat loop) or is there a better way? Thank you!

-- servers
local ServerStorage = game:GetService("ServerStorage")

-- folders
local npcs = ServerStorage:WaitForChild("NPCS")
local npcsChildren = npcs:GetChildren()

local lineParts = workspace:WaitForChild("LineParts")
local linePartsChildren = lineParts:GetChildren()

local lastNpc = tick()
local npcWaitTime = 5

local customerLine = {}

-- functions
function randomNpc()
	local randomNpc = math.random(1, #npcsChildren)
	local chosenNpc = npcsChildren[randomNpc]:Clone()
	chosenNpc.Parent = workspace
	
	return chosenNpc
end

function findPositionInLine(chosenNpc)
	local positionInLine = table.find(customerLine, chosenNpc)
	local chosenLinePart = linePartsChildren[positionInLine]
	chosenNpc.Humanoid:MoveTo(chosenLinePart.Position)
end
-- line


repeat wait()
	for i = #customerLine, 1, -1 do
		local customer = customerLine[i]
		if customer == nil or customer.Parent == nil or customer.Humanoid.Health <= 0 then
			table.remove(customerLine, i)
			lastNpc = tick()
		end
	end
	for i, npc in pairs(customerLine) do
		findPositionInLine(npc)
	end
	if #customerLine < #linePartsChildren then
		print(tick()-lastNpc)
		if tick() - lastNpc >= npcWaitTime then
			lastNpc = tick()
			local newNpc = randomNpc()
			table.insert(customerLine, newNpc)
			findPositionInLine(newNpc)
		end
	end
until false
6 Likes

Your current method of moving NPCs is functional, but there are some potential improvements you can make to optimize it. Here’s a modified version of your script using tweens instead of MoveTo() and removing the infinite repeat loop:

-- services
local ServerStorage = game:GetService("ServerStorage")
local TweenService = game:GetService("TweenService")

-- folders
local npcs = ServerStorage:WaitForChild("NPCS")
local npcsChildren = npcs:GetChildren()

local lineParts = workspace:WaitForChild("LineParts")
local linePartsChildren = lineParts:GetChildren()

local npcWaitTime = 5
local customerLine = {}

-- functions
function randomNpc()
    local randomNpc = math.random(1, #npcsChildren)
    local chosenNpc = npcsChildren[randomNpc]:Clone()
    chosenNpc.Parent = workspace
    
    return chosenNpc
end

function findPositionInLine(chosenNpc)
    local positionInLine = table.find(customerLine, chosenNpc)
    local chosenLinePart = linePartsChildren[positionInLine]
    
    local tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
    local goal = { CFrame = chosenLinePart.CFrame }
    local tween = TweenService:Create(chosenNpc.HumanoidRootPart, tweenInfo, goal)
    tween:Play()
end

function spawnNPC()
    local newNpc = randomNpc()
    table.insert(customerLine, newNpc)
    findPositionInLine(newNpc)
end

-- Spawning and moving NPCs
spawnNPC()
while wait(npcWaitTime) do
    for i = #customerLine, 1, -1 do
        local customer = customerLine[i]
        if customer == nil or customer.Parent == nil or customer.Humanoid.Health <= 0 then
            table.remove(customerLine, i)
        end
    end
    for i, npc in pairs(customerLine) do
        findPositionInLine(npc)
    end
    if #customerLine < #linePartsChildren then
        spawnNPC()
    end
end

This version of the script utilizes tweens instead of the MoveTo() function, which provides smoother and more customizable movement for the NPCs. Additionally, instead of using an infinite repeat loop, the script uses a while loop with the wait() function, which helps to prevent potential performance issues.

With this updated script, you can easily adjust the NPC movement speed and other properties by modifying the TweenInfo parameters.

4 Likes

Hi! I tried using the script but my NPCs are clipping through the ground. I think this is because the script tweens the humanoid root part. Would there be a way to prevent this?

2 Likes

Tween the HumanoidRootPart to the parts position but offset the vector Y by however many studs

2 Likes

Because you’re using a part, try using the Touched event to update the table. And whenever the npc is done with the cashier you could use TouchedEnded to update the table once again.

1 Like

did bro just chatgpt a response? :face_exhaling:

1 Like