The while loop runs several times, in theory it should break when the mouse moves away from the UI element, but this only works when the mouse leaves and waits a few seconds and only then goes back to the UI element, if it does this without waiting, the loop will start several times and the images will start blinking. What could be the reason?
Issue:
Code:
local MouseOnWindow = false
SkyFrame.SkyImage.MouseEnter:Connect(function()
MouseOnWindow = true
local InnerAngles = {}
for Key, Angle in SkyboxAngles do
if not table.find(InnerAngles, Element[Angle]) then
InnerAngles[Key] = Element[Angle]
end
end
local NextAngle = if #InnerAngles > 1 then if InnerAngles[1] == SkyFrame.SkyImage then 2 else 1 else 1
while MouseOnWindow do
SkyFrame.LastSkyImage.Image = SkyFrame.SkyImage.Image
SkyFrame.LastSkyImage.ImageTransparency = 0
SkyFrame.SkyImage.ImageTransparency = 1
NextAngle = if NextAngle < #InnerAngles then NextAngle + 1 else 1
SkyFrame.SkyImage.Image = InnerAngles[NextAngle]
TweenService:Create(SkyFrame.LastSkyImage, TweenInfo.new(.15, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {
ImageTransparency = 1
}):Play()
TweenService:Create(SkyFrame.SkyImage, TweenInfo.new(.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
ImageTransparency = 0
}):Play()
task.wait(1.15)
end
end)
SkyFrame.SkyImage.MouseLeave:Connect(function()
MouseOnWindow = false
if SkyFrame.SkyImage ~= Element.SkyboxFt then
SkyFrame.LastSkyImage.Image = SkyFrame.SkyImage.Image
SkyFrame.LastSkyImage.ImageTransparency = 0
SkyFrame.SkyImage.ImageTransparency = 1
SkyFrame.SkyImage.Image = Element.SkyboxFt
TweenService:Create(SkyFrame.LastSkyImage, TweenInfo.new(.15, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {
ImageTransparency = 1
}):Play()
TweenService:Create(SkyFrame.SkyImage, TweenInfo.new(.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
ImageTransparency = 0
}):Play()
end
end)
while MouseOnWindow do
SkyFrame.LastSkyImage.Image = SkyFrame.SkyImage.Image
SkyFrame.LastSkyImage.ImageTransparency = 0
SkyFrame.SkyImage.ImageTransparency = 1
NextAngle = if NextAngle < #InnerAngles then NextAngle + 1 else 1
SkyFrame.SkyImage.Image = InnerAngles[NextAngle]
TweenService:Create(SkyFrame.LastSkyImage, TweenInfo.new(.15, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {
ImageTransparency = 1
}):Play()
TweenService:Create(SkyFrame.SkyImage, TweenInfo.new(.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
ImageTransparency = 0
}):Play()
task.wait(1.15) -- Culprit
end
Basically, the conditional statement is checked again after the 1.15 seconds have passed. So it’s equivalent to:
if MouseOnWindow then
-- Code
end
task.wait(1.15) -- Wait 1.15
if MouseOnWindow then
-- Code
end
-- Keep repeating this process
The reason it repeats several times is because if you don’t wait the 1.15 seconds after the MouseLeave event, then the loop never ends because triggering the MouseEnter event will cause MouseOnWindow to still be equal to true. MouseOnWindow doesn’t have a unique value for each loop (it’s only true to get it to run). My suggestion would be to change the value from true to something like os.time() and replace:
while MouseOnWindow do
-- Rest of code
end
with:
local current = os.time()
MouseOnWindow = current
while MouseOnWindow == current do
-- Rest of code
end
This way, the loop would break if the current os.time() is not equal to the one that the loop checks. Hope this made sense and helps . If you have any questions, let me know
Thanks for the answer! It looks like while has been changed, because as far as I remember it didn’t work like that before. Previously, he constantly checked the condition, and then broke the loop without performing the following actions, but now apparently he was assigned the same logic as in
Loops have always worked like this. This is true for every programming language. A loop is just a block of code that is repeated x amount of times or until the conditional statement in a while loop is equal to false. The conditional statement does not get checked during every line inside the loop. Only the first. So an example would be like:
local ThisIsTrue = true
while (ThisIsTrue) do — Line 1 of loop, this is true so run block of code!
print(“Segment 1”)
print(“Segment 2”)
end — End of loop. Go back to line 1 of loop.
task.wait(1.15) yields the loop at the line it’s at for the (roughly) 1.15 seconds. So let’s say that you trigger the MouseLeaveevent but then trigger the MouseEnter event before the 1.15 second yield time has ended. The loop refers back to the first line and checks of the variable is true (which it is in this case) so it keeps running. You can even set the variable to false within the loop and it would still run as long as you trigger the MouseEnter event before the 1.15 second yield is complete:
while MouseOnWindow do
MouseOnWindow = false
task.delay(0.5, function()
MouseOnWindow = true —This will cause the loop to still run because the variable is set back to true before the 1.15 second yield is completed
end)
task.wait(1.15)
end
In theory, it should create a unique conditional statement for every while loop created. This would allow the loop to break on it’s own whenever the variable no longer equals the unique value (os.time() in that example). Kinda like giving the loop it’s own unique key in a way. There’s plenty of other ways to do it. You can simply increment a value before the loop is created:
local current = 0
SkyFrame.SkyImage.MouseEnter:Connect(function()
-- Code
current += 1
local key = current -- Store current's value in a separate variable
MouseOnWindow = key -- Assign the variable to the value of "current"
while MouseOnWindow == key do -- Checks if the variable is still equal to the value that was set before the loop was ran
-- Code
end
end)
So for example, if current was 0. MouseOnWindow would be set to 1 when MouseEnter is triggered and the loop will check if MouseOnWindow is equal to this number everytime it is ran. If you trigger the MouseEnter event again, MouseOnWindow’s value gets changed to 2. This causes the first loop to end, as the conditional statement is false:
while MouseOnWindow == key do -- This is false as key is equal to 1 and MouseOnWindow is equal to 2
-- Code
end