Hey. So I am making an order board, which has several parts inside of it. It moves decals from the highest to lowest numbered part.
This script works, but I dont think using while true do is efficient.
local next = script.Parent.Parent:FindFirstChild(script.Parent.Name - 1) -- Finds next space
--------------------Detects next box for Decal, if false, moves "next"-------------------------
while true do -- Loop Script
repeat wait() until
script.Parent:FindFirstChildOfClass("Decal") ~= nil and -- If current order true and next order nil, continue
next:FindFirstChildOfClass("Decal") == nil
if next:FindFirstChildOfClass("Decal") == nil then -- If next order nil, move current order forward
wait(2)
local g = script.Parent:GetChildren()
for i = 1 ,#g do
if g[i].className == "Decal" then
repeat wait() until next:FindFirstChildOfClass("Decal") == nil
g[i].Parent = next
end
end
end
end
You can use RunService and you can use task.wait() instead of wait() because the task library allows u to communicate directly with the game engine’s task schedular.
Here is a link to Task Library if u want to know more about it!
If you can, try to use and somehow implement GetPropertyChangedSignal() instead of while loops in your code.
I tried to understand and rewrite the function of your code, and here’s what I came up with:
local next = script.Parent.Parent[tostring(tonumber(script.Parent.Name) - 1)]
script.Parent.ChildAdded:Connect(function(child)
if child.ClassName ~= "Decal" then return end
if next:FindFirstChildOfClass("Decal") then return end
wait(2)
local decals = script.Parent:GetChildren()
for _,d in ipairs(decals) do
if d:IsA("Decal") then
d.Parent = next
end
end
end)
I think its to do with the function
script.Parent.ChildAdded:Connect(function(child)
I dont really understand why it wouldnt do anything though.
Does the script need to be a Local Script? I dont think using that type would be a good idea though.
I tested and came up with this script that changes the parent of a Decal to the parts in descending order based on name. Feel free to try it out:
local parts = script.Parent:GetChildren()
table.foreachi(parts, function(i, v)
if not v:IsA("BasePart") then table.remove(parts, i) end
end)
table.sort(parts, function(a, b)
return (tonumber(a.Name) or 0) < (tonumber(b.Name) or 0)
end)
for i,p in ipairs(parts) do
local function onChildAdded(child)
if not child:IsA("Decal") then return end
local nextPart = parts[i - 1] or parts[#parts]
if nextPart:FindFirstChildOfClass(child.ClassName) then return end
task.wait(2)
child.Parent = nextPart
end
p.ChildAdded:Connect(onChildAdded)
for _,c in ipairs(p:GetChildren()) do onChildAdded(c) end
end
If you need something that runs a lot but don’t necessarily need a “while true do” as such, and your code revolves around something that is often changing, you’re potentially better off with Instance.Property.Changed:Connect()
If you absolutely must have a while true do, and you will never ever want to escape it, you can cut down on lines/make it cleaner by making it while wait() do instead. Does the same as putting a wait() in a while true do loop, just a lot less characters.
I don’t think you have to be worried about that, unless you are using an unhealthy amount of remote events and remote functions. Also, you might wanna include a wait of sorts in the while loop.