Hello-
I'm working on creating a basic GUI that lists a Queue of "Announcements" in this case that can be prioritized based on a value. When a new announcement is created, I'd like it to appear in the appropriate space(Like 4 appearing between 3 and 5). I don't have any experience with Queue-making and I am wondering what the most efficient way to do this would be.
Below is a really simple little program that kinda outlines the basis of what I'm trying to do, but I'm still a bit lost so any help provided is great, Thanks!
local Integer = 1 script.Parent.TextButton.MouseButton1Down:connect(function(hit) print("Creating New Announcement") local Announcement = script.Parent.TextBox:Clone() Announcement.Parent = script.Parent Announcement.Visible = true Announcement.Position = UDim2.new(0,0,0.1*Integer,0) Integer = Integer +1 wait(5)--Destroys GUI after a while and reduces Integer again. Announcement:Destroy() Integer = Integer - 1 end)
You have Objectives. They stay open until they are somehow cleared.
Here's one way you can organize it.
There are two important functions:
-- Add a new objective with a given priority function Add(objective, priority) end -- Display all unsolved objectives function ShowAll() end
We'll need a list of all of the objectives currently open, and we'll need Add
to put into it something that has (1) the objective data, (2) something saying it's still open, and (3) the priority.
You might also want to add, e.g., a Frame so that you can do animations when there are updates, instead of just erasing and updating everything in ShowAll
. I'll show that here.
local objectives = {} -- All open objectives function Add(objective, priority) local o = { data = objective, priority = priority } o.gui = Instance.new("Frame", script.Parent) o.gui.Position = UDim2.new(0.5, 0, 0.5, 0) o.gui.Size = UDim2.new(0, 0, 0, 0) -- Add text labels or whatever: local label = Instance.new("TextLabel", o.gui) label.Text = objective label.TextScaled = true label.BackgroundTransparency = 1 -- Update the view every time there's a new priority: ShowAll() return o end
We can also add a Complete
function which gets rid of the o.gui
:
function Complete(objective) o.gui:TweenSize( UDim2.new(0,0,0,0), nil, nil, 1, true) delay(1, function() o.gui:Destroy() end) end
Now we need ShowAll
to (1) clear solved objectives, (2) sort current objectives, and (3) display the objectives
.
table.remove
can remove something at a given index. The simplest way to make this work is a for
loop that moves from back to front (since table.remove
shifts all the indices down, going up doesn't work).
Sorting is easy with table.sort
. We can give a function telling how to compare to objects, which puts larger .priority
fields first:
function ShowAll() for i = #objectives, 1, -1 do if objectives[i].cleared then Complete( table.remove(objectives, i) ) end end table.sort(objectives, function(a,b) return a.priority > b.priority end)
You then should choose to display either the first or all objectives. Here I'll display the first, and the rest separately:
if objectives[1] then objectives[1].gui:TweenPosition(UDim2.new(0,0,0,0)) objectives[1].gui.TweenSize(UDim2.new(1, 0, 0, 72)) end for i = 2, #objectives do objectives[i].gui:TweenPosition(UDim2.new(1, -100, 0, 72+(i-2)*36), nil, nil, 1, true) objectives[i].gui:TweenSize(UDim2.new(0, 100, 0, 36), nil, nil, 1, true) end end
To finish an objective, you should add cleared
onto the thing that Add
returns:
local objective = Add("Wait 10 seconds", 1) wait(10) objective.cleared = true ShowAll() -- update
It may be reasonable to simply ShowAll
on a loop every one second instead. Note that if you interrupt Tweens, it will look a little strange, so if you have very frequent updates, you might run into some issues.
Also be aware that this is not fast. Sorting hundreds or thousands of elements when you add one thing isn't the fastest -- but if you have less than a few dozen it'll still be instant