What do you want to achieve? I want to create a for i, v in pairs() function to make a door closing function.
What is the issue? The game treats my code as a for loop, which causes it to be repeated forever. Here’s the code:
a.Frame.DoorR.MouseButton1Click:Connect(function()
if RDoorsOpen == true then
RDoorsOpen = false
for i, v in pairs(doors.R:GetDescendants()) do
if v.Name == "Prismatic" then
v.TargetPosition = 1.87
a.Frame.DoorR.Text = "Closing Right Doors"
wait(.9)
for is, v in pairs(model:GetDescendants()) do
if v.Name == "DoorClose" then
v:Play()
print("door close has played")
for i, v in pairs(doors.R:GetDescendants()) do
if v.Name == "Frame" then
v.CanCollide = true
a.Frame.DoorR.Text = "Open Right Doors"
print("loop over")
end
end
end
end
end
end
end
end)
What solutions have you tried so far? I could not find any solutions on the DevForum.
Can you post where model is defined? Also show your explorer for doors.R?
I see you have a lot of loops inside loops, if there is only one descendant named “Prismatic” and/or “DoorClose” you could just use local v = doors.R:FindFirstChild("Prismatic", true)
If doors.R has a lot of descendants then this function will run exponentially long, for every child added it will take another n^2 cycles, widely regarded as a bad sign in performance.
It’s difficult to know the exact issue without seeing the model hierarchy but I’d suggest an approach like this instead:
a.Frame.DoorR.MouseButton1Click:Connect(function()
if RDoorsOpen == true then
RDoorsOpen = false
local prismaticDoor = doors.R:FindFirstChild("Prismatic", true)
local doorClose = model:FindFirstChild("DoorClose", true)
local frame = doors.R:FindFirstChild("Frame", true)
if prismaticDoor and doorClose and frame then
prismaticDoor.TargetPosition = 1.87
a.Frame.DoorR.Text = "Closing Right Doors"
task.wait(0.9)
doorClose:Play()
frame.CanCollide = true
a.Frame.DoorR.Text = "Open Right Doors"
end
end
end)
The image is showing the hierarchy of where doors.R is located.
Model is defined as the model R9.
doors.R contains multiple "Prismatic"s and multiple "Frame"s and I want to change all of them simultaneously, which is why I chose to use for i, v in pairs().
is doorClose a sound or a tween? If it’s a tween then it’s going to need to be ran for each individual door. Do you want these doors all closing at the same time (concurrently), or one after the other (sequentially)?
This will still need some tuning but it plays the sound once for all doors, and iterates over each Prismatic and after 0.9 seconds on each one it sets that door’s corresponding Frame.canCollide = true.
a.Frame.DoorR.MouseButton1Click:Connect(function()
if RDoorsOpen == true then
RDoorsOpen = false
local doorClose = model:FindFirstChild("DoorClose", true)
local doorClosePlayed = false
for _, prismatic in doors.R:GetDescendants() do
if prismatic.Name == "Prismatic" then
prismatic.TargetPosition = 1.87
-- Only play once for all the doors
if not doorClosePlayed then
doorClosePlayed = true
doorClose:Play()
end
-- Set the door's frame to collide after 0.9 seconds
task.delay(0.9, function()
prismatic.Parent.Parent.Frame.CanCollide = true
end)
end
end
end
end)
Where do they live in the object hierarchy? Are they inside Frame or Window? Let’s pretend they’re a child of frame. If so you could play it inside the task.delay()
Maybe it would be better to find those before the function call. (same with prismatic and frames) assuming they do not move in the hierarchy?
local doorSounds = {}
for _, doorSound in model:GetDescendants() do
if doorSound.Name == "DoorClose" then
table.insert(doorSounds, doorSound)
end
end
a.Frame.DoorR.MouseButton1Click:Connect(function()
if RDoorsOpen == true then
RDoorsOpen = false
for _, doorSound in doorSounds do
doorSound:Play()
end
None of these solutions truly worked, and were either extremely buggy, or didn’t do what I want. I was able to apply concepts, however, to create a script that would go around having to put for loops inside of eachother.
Final Script:
a.Frame.DoorR.MouseButton1Click:Connect(function()
if RDoorsOpen == true then
RDoorsOpen = false
a.Frame.DoorR.Text = "Closing Right Doors"
for i, v in pairs(doors.R:GetDescendants()) do
if v.Name == "Prismatic" then
v.TargetPosition = 1.86
end
end
for i, v in pairs(model:GetDescendants()) do
if v.Name == "DoorClose" then
v:Play()
end
end
wait(0.9)
a.Frame.DoorR.Text = "Open Right Doors"
for i, v in pairs(doors.R:GetDescendants()) do
if v.Name == "Frame" then
v.CanCollide = true
end
end
elseif RDoorsOpen == false then
RDoorsOpen = true
a.Frame.DoorR.Text = "Opening Right Doors"
for i, v in pairs(doors.R:GetDescendants()) do
if v.Name == "Prismatic" then
v.TargetPosition = 0
end
end
for i, v in pairs(doors.R:GetDescendants()) do
if v.Name == "Frame" then
v.CanCollide = false
end
end
for i, v in pairs(model:GetDescendants()) do
if v.Name == "Open" then
v:Play()
end
end
wait(0.9)
a.Frame.DoorR.Text = "Close Right Doors"
end
end)