I am writing a code for a GUI that gives you clothing options. The GUI-related scripting works just fine, but it only works on one of the parts that trigger the GUI. I put all of the parts in a folder and tried using GetChildren, but it still only works for the first child.
Here's the script
local Mouse = Player:GetMouse()
local UIS = game:GetService("UserInputService")
local peeking = false
for i,v in pairs(workspace.Closets:GetChildren()) do
UIS.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.E then
if Mouse.Target == v then
Player.PlayerGui.ClosetHandler.Change.Visible = true
end
end
end)
Mouse.Button1Down:Connect(function()
if Mouse.Target == v then
Player.PlayerGui.ClosetHandler.Change.Visible = true
end
end)
local peeking = false
while true do
wait()
if Mouse.Target == v then
if peeking == false then
peeking = true
local bClone = script.Parent.Button:Clone()
bClone.Parent = workspace.CurrentCamera
bClone.Adornee = v
bClone.TextLabel.Visible = true
end
else
if peeking == true then
if workspace.CurrentCamera:FindFirstChild("Button") then
workspace.CurrentCamera.Button:remove()
peeking = false
end
end
end
end
end
I think it may have to do with the lines using v (ex: if Mouse.Target == v then
) but I am not sure.
The reason this is happening is because of your while loop. The program will not continue onto the next item in the for loop because it is stuck executing the code in the while loop. To get around this, you can enclose the while loop in the spawn()
function. This starts another thread that executes alongside your existing thread, allowing the existing thread to continue onto the next item in the loop. In your case, you would write it like so:
spawn(function()
while true do
wait()
if Mouse.Target == v then
if peeking == false then
peeking = true
local bClone = script.Parent.Button:Clone()
bClone.Parent = workspace.CurrentCamera
bClone.Adornee = v
bClone.TextLabel.Visible = true
end
else
if peeking == true then
if workspace.CurrentCamera:FindFirstChild("Button") then
workspace.CurrentCamera.Button:remove()
peeking = false
end
end
end
end
end)
Keep in mind, however, you MUST include a way for this loop to terminate after you’re done using it. Somewhere inside that loop, check to see if the loop still needs to be running. If not, then return
the function so that the loop stops. Otherwise, you’ll end up opening hundreds if not thousands of duplicate threads which will eventually crash your game.
This is just one of many ways to solve this problem and is my preferred method.
1 Like
Thanks! That works great! One last question though. Is there any way for me to verify that I’ve terminated the loop? I could do print "Terminated"
with Output, but don’t know what that would look like when it properly terminates.
1 Like
As long as you have a return
statement inside the loop, it effectively terminates the function that we’ve passed through spawn()
. Otherwise, you could include a print()
statement inside of the loop to know that you’ve terminated it.