Basically, my client script runs all of the four menu buttons and is taking way too long to complete.
The script will allow for buttons to be made based on a few modules. It’s taking around 30-60 seconds to fully complete.
I apologize in advance for the long code but I’m just confused on how this is taking so long. There are no wait()
to slow it down. (only waits are in some functions which don’t run unless called)
I’m not quite sure if this counts as code review so I’ll leave it in scripting support unless someone can confirm.
local player = game:GetService('Players').LocalPlayer
--Services
local Rep = game:GetService("ReplicatedStorage")
local PlayerGui = player:WaitForChild("PlayerGui")
local MPS = game:GetService("MarketplaceService")
local Teams = game:GetService("Teams")
--Variables
local Modules = Rep:FindFirstChild("Modules")
local Menu = PlayerGui:WaitForChild("Menu")
local AnimationsFrame = Menu:FindFirstChild("Animations")
local GamepassesFrame = Menu:FindFirstChild("Gamepasses")
local SubMenuFrame = Menu:FindFirstChild("Menu")
local SubMenuFrameButtons = SubMenuFrame:FindFirstChild("Buttons")
local TeamsFrame = Menu:FindFirstChild("Teams")
local UniformsFrame = Menu:FindFirstChild("Uniforms")
local Remotes = Rep:FindFirstChild("Remotes")
local R_Event = Remotes:FindFirstChild("MenuEvent")
local AccessorieRemove = UniformsFrame:FindFirstChild("Frame"):FindFirstChild('AccessoriesDelete')
local udim = UDim2.new
local CanToggleMenu = true
local AnimationsFolder = script:FindFirstChild("Animations")
local CurrentPlayingAnimation
local CanAnimate = true
--Modules
local PurchaseableMod = require(Modules.PurchaseableItems)
local UniformsMod = require(Modules.Uniforms)
local GamepassesMod = require(Modules.Gamepasses)
local AccessoriesMod = require(Modules.Accessories)
local TeamsMod = require(Modules:WaitForChild("Teams"))
wait()
local SaveOutfit = UniformsFrame:FindFirstChild('Frame'):FindFirstChild('OutfitSave')
local PlayerValues = Rep:WaitForChild('PlayerValues')
local myValue = PlayerValues:WaitForChild("uid_"..player.UserId)
local EnableCustom = myValue:WaitForChild('EnableCustom')
--Tables
warn('Main Client..')
Menu.Gamepasses.Visible = true
local TweenFrames = {
{
Frame = SubMenuFrame,
ToggleButton = SubMenuFrame.Open,
ClosedTween = udim(-.1,0,.356,0),
OpenTween = udim(.005,0,.356,0),
TweenDirection = Enum.EasingDirection.InOut,
TweenStyle = Enum.EasingStyle.Linear,
Time = .2,
},
{
Frame = AnimationsFrame,
ToggleButton = SubMenuFrameButtons.AnimationPadding.Animations,
CloseButton = AnimationsFrame.Close,
ClosedTween = udim(-.4,0,.7,0),
OpenTween = udim(0,10,.7,0),
TweenDirection = Enum.EasingDirection.InOut,
TweenStyle = Enum.EasingStyle.Linear,
Time = .2,
},
{
Frame = GamepassesFrame,
ToggleButton = SubMenuFrameButtons.GamepassesPadding.Gamepasses,
CloseButton = GamepassesFrame.Close,
ClosedTween = udim(-.4,0,.25,0),
OpenTween = udim(.325,0,.25,0),
TweenDirection = Enum.EasingDirection.InOut,
TweenStyle = Enum.EasingStyle.Linear,
Time = .2,
FramesToClose = {TeamsFrame,UniformsFrame}
},
{
Frame = TeamsFrame,
ToggleButton = SubMenuFrameButtons.TeamPadding.Teams,
CloseButton = TeamsFrame.Close,
ClosedTween = udim(-.4,0,.25,0),
OpenTween = udim(.3,0,0.044,0),
TweenDirection = Enum.EasingDirection.InOut,
TweenStyle = Enum.EasingStyle.Linear,
Time = .2,
FramesToClose = {GamepassesFrame,UniformsFrame}
},
{
Frame = UniformsFrame,
ToggleButton = SubMenuFrameButtons.UniformsPadding.Uniforms,
CloseButton = UniformsFrame.Close,
ClosedTween = udim(-.6,0,.25,0),
OpenTween = udim(0.235, 0,0.206, 0),
TweenDirection = Enum.EasingDirection.InOut,
TweenStyle = Enum.EasingStyle.Linear,
Time = .2,
FramesToClose = {GamepassesFrame,TeamsFrame}
},
}
local MainFrames = {
AnimationsFrame,
GamepassesFrame,
TeamsFrame,
UniformsFrame,
}
local Buttons = {
{Button = GamepassesFrame.Buttons.DevProducts, ActionFrame = GamepassesFrame.DevProducts, Type = "Open", FramesToClose = {GamepassesFrame.Gamepasses}},
{Button = GamepassesFrame.Buttons.Gamepasses, ActionFrame = GamepassesFrame.Gamepasses, Type = "Open", FramesToClose = {GamepassesFrame.DevProducts}},
{Button = UniformsFrame.Buttons.Accessories, ActionFrame = UniformsFrame.Accessories, Type = "Open", FramesToClose = {UniformsFrame.Allied,UniformsFrame.Army,UniformsFrame.Covers,UniformsFrame.Faces,UniformsFrame.Intelligence}},
{Button = UniformsFrame.Buttons.Allied, ActionFrame = UniformsFrame.Allied, Type = "Open", FramesToClose = {UniformsFrame.Accessories,UniformsFrame.Army,UniformsFrame.Covers,UniformsFrame.Faces,UniformsFrame.Intelligence}},
{Button = UniformsFrame.Buttons.Army, ActionFrame = UniformsFrame.Army, Type = "Open", FramesToClose = {UniformsFrame.Accessories,UniformsFrame.Allied,UniformsFrame.Covers,UniformsFrame.Faces,UniformsFrame.Intelligence}},
{Button = UniformsFrame.Buttons.Covers, ActionFrame = UniformsFrame.Covers, Type = "Open", FramesToClose = {UniformsFrame.Accessories,UniformsFrame.Allied,UniformsFrame.Army,UniformsFrame.Faces,UniformsFrame.Intelligence}},
{Button = UniformsFrame.Buttons.Faces, ActionFrame = UniformsFrame.Faces, Type = "Open", FramesToClose = {UniformsFrame.Accessories,UniformsFrame.Allied,UniformsFrame.Army,UniformsFrame.Covers,UniformsFrame.Intelligence}},
{Button = UniformsFrame.Buttons.Intelligence, ActionFrame = UniformsFrame.Intelligence, Type = "Open", FramesToClose = {UniformsFrame.Accessories,UniformsFrame.Allied,UniformsFrame.Army,UniformsFrame.Covers,UniformsFrame.Faces}},
}
local Animations = {
["Salute1"] = AnimationsFolder.Salute1,
["Salute2"] = AnimationsFolder.Salute2,
["At-Ease1"] = AnimationsFolder.AtEase1,
["At-Ease2"] = AnimationsFolder.AtEase2,
["Push-ups"] = AnimationsFolder.Pushups,
["Salute1Hold"] = AnimationsFolder.Salute1Hold,
["At-Ease1Hold"] = AnimationsFolder.AtEaseHold,
}
local LoadedAnimations = {}
local ConnectedAnimations = {
["Salute"] = {[1] = "Salute1",[2] = "Salute2"},
["At-Ease"] = {[1] = "At-Ease1",[2] = "At-Ease2"}
}
local GamepassCache = {}
--Pre-initialization
for i,v in pairs(Animations) do
LoadedAnimations[tostring(i)] = {nil}
end
--Functions
local function Fire(action,args)
R_Event:FireServer(action,args)
print('fioreeeeeeeee')
end
function InteractAnim(action)
if action == "Stop" then
if CurrentPlayingAnimation ~= nil and LoadedAnimations[CurrentPlayingAnimation][1] ~= nil then
LoadedAnimations[CurrentPlayingAnimation][1]:Stop()
CurrentPlayingAnimation = nil
end
elseif action == "Play" then
if player and player.Character and player.Character:FindFirstChild("Humanoid") then
if LoadedAnimations[CurrentPlayingAnimation][1] == nil then
LoadedAnimations[CurrentPlayingAnimation][1] = player.Character.Humanoid:LoadAnimation(Animations[CurrentPlayingAnimation])
end
if LoadedAnimations[CurrentPlayingAnimation][1] ~= nil then
LoadedAnimations[CurrentPlayingAnimation][1]:Play()
if CurrentPlayingAnimation == "Salute1" or CurrentPlayingAnimation == "At-Ease1" then
wait(.25)
local newAnimName = CurrentPlayingAnimation.."Hold"
InteractAnim("Stop")
CurrentPlayingAnimation = newAnimName
InteractAnim("Play")
end
if CurrentPlayingAnimation == "Salute2" or CurrentPlayingAnimation == "At-Ease2" then
wait(.25)
CurrentPlayingAnimation = nil
InteractAnim("Stop")
end
end
end
end
end
local function AnimatePlayer(animationName)
if CanAnimate then
CanAnimate = false
if LoadedAnimations[animationName] and LoadedAnimations[animationName] ~= nil then
if CurrentPlayingAnimation == animationName then
InteractAnim("Stop")
else
CurrentPlayingAnimation = animationName
InteractAnim("Play")
end
else
for i,v in pairs(ConnectedAnimations) do
if i == animationName then
for x,d in pairs(v) do
if CurrentPlayingAnimation ~= nil and string.sub(CurrentPlayingAnimation,1,#i) == i then
if d == string.sub(CurrentPlayingAnimation,1,#d) then
InteractAnim("Stop")
if #v >= x+1 then
CurrentPlayingAnimation = v[x+1]
InteractAnim("Play")
end
break
end
else
InteractAnim("Stop")
CurrentPlayingAnimation = v[1]
InteractAnim("Play")
break
end
end
break
end
end
end
wait(1)
CanAnimate = true
end
end
local function CreateNewTemplate(template,parent)
local template = template:Clone()
template.Parent = parent
return template
end
local function Purchase(id,Type)
Fire("PromptPurchase",{Id = id, Type = Type})
end
local function TweenOut(frame)
for i,v in pairs(TweenFrames) do
if v.Frame == frame then
CanToggleMenu = false
frame:TweenPosition(v.ClosedTween,v.TweenDirection,v.TweenStyle,v.Time)
wait(v.Time)
CanToggleMenu = true
return
end
end
return false
end
--//INITIALIZATION\\
warn('INITIALIZATION..')
for i,v in pairs(GamepassesMod) do
for x,d in pairs(v) do
local id = d
local t = CreateNewTemplate(GamepassesFrame.Template,GamepassesFrame[i])
local itemType
if i == "Gamepasses" then
itemType = 2
elseif i == "DevProducts" then
itemType = 1
end
local productinfo = MPS:GetProductInfo(id,itemType)
local imageid,price = productinfo.IconImageAssetId,productinfo.PriceInRobux
t:WaitForChild('ImageFrame').ImageLabel.Image = "rbxassetid://"..imageid
t.TextFrame.Title.Text = x .. " - R$" .. price
t.TextFrame.Purchase.MouseButton1Down:connect(function()
Purchase(id,i)
end)
t.Visible = true
end
end
for i,v in pairs(TeamsMod) do
local t = CreateNewTemplate(TeamsFrame.Template,TeamsFrame.ScrollingFrame)
t.Frame.TextLabel.Text = i
t.Visible = true
t.Frame.TextButton.MouseButton1Down:connect(function()
if player.Team.Name ~= "Visitors" and i == "Raiders" then
-- no
else
Fire("ChangeTeam",{TeamName = i})
end
end)
end
warn('INT1A')
for i,v in pairs(PurchaseableMod) do
local t = CreateNewTemplate(UniformsFrame.Template,UniformsFrame.Faces)
local id = v.id
local productinfo = MPS:GetProductInfo(id,2)
local imageid,price = productinfo.IconImageAssetId,productinfo.PriceInRobux
t.ImageFrame.ImageLabel.Image = "rbxassetid://"..v.decalID
t.TextFrame.TextLabel.Text = i .. " - R$" .. price
GamepassCache[id] = t
if not MPS:UserOwnsGamePassAsync(player.UserId,id) then
t.TextFrame.TextButton.Text = "Purchase"
end
t.TextFrame.TextButton.MouseButton1Down:connect(function()
if not MPS:UserOwnsGamePassAsync(player.UserId,id) then
Purchase(id,"Gamepasses")
else
Fire("Equip", {Type = "Face",Id = id})
end
end)
t.Visible = true
end
warn('INITIALIZATION2..')
for i,v in pairs(UniformsMod) do
for x,d in ipairs(v.Items) do
if d.shirt ~= nil then
local t = CreateNewTemplate(UniformsFrame.Template,UniformsFrame[i])
t.TextFrame.TextLabel.Text = d.name
t.ImageFrame.ImageLabel.Image = "rbxassetid://"..d.guiImage
t.TextFrame.TextButton.MouseButton1Down:connect(function()
Fire("Equip", {Type = "Uniform",Group = i,Name = d.name})
end)
t.Visible = true
end
if #d.helmet >= 1 then
for int,obj in pairs(d.helmet) do
local t = CreateNewTemplate(UniformsFrame.Template,UniformsFrame.Covers)
t.TextFrame.TextLabel.Text = d.helmet[1].Name
t.ImageFrame.ImageLabel.Image = "rbxassetid://"..d.helmetImage
t.TextFrame.TextButton.MouseButton1Down:connect(function()
Fire("Equip", {Type = "Cover",Group = i,Name = d.helmet[1].Name})
end)
t.Visible = true
end
end
end
end
for i,v in pairs(AccessoriesMod) do
local t = CreateNewTemplate(UniformsFrame.Template,UniformsFrame["Accessories"])
t.TextFrame.TextLabel.Text = i
local itemInfo = MPS:GetProductInfo(v.GPId, Enum.InfoType.GamePass)
t.ImageFrame.ImageLabel.Image = "rbxassetid://"..itemInfo.IconImageAssetId
if MPS:UserOwnsGamePassAsync(player.UserId,v.GPId) then
t.TextFrame.TextButton.Text = "Equip"
else
t.TextFrame.TextButton.Text = "Purchase"
end
t.Visible = true
t.TextFrame.TextButton.MouseButton1Down:connect(function()
if not MPS:UserOwnsGamePassAsync(player.UserId,v.GPId) then
Purchase(v.GPId,"Gamepasses")
else
Fire("Equip", {Type = "Accessory",Name = i})
end
end)
GamepassCache[v.GPId] = t
end
warn('INITIALIZATION3..')
for i,v in pairs(TweenFrames) do
--v.Frame.Position = v.ClosedTween
v.ToggleButton.MouseButton1Down:connect(function()
if CanToggleMenu == true then
CanToggleMenu = false
local EaseType
if v.Frame.Position == v.ClosedTween then
EaseType = "OpenTween"
else
EaseType = "ClosedTween"
end
if v.FramesToClose then
for x,d in pairs(v.FramesToClose) do
local tween = TweenOut(d)
if tween == false then
d.Visible = false
end
end
end
v.Frame:TweenPosition(v[EaseType],v.TweenDirection,v.TweenStyle,v.Time)
wait(v.Time)
CanToggleMenu = true
if v.CloseButton then
v.CloseButton.MouseButton1Down:connect(function()
TweenOut(v.Frame)
end)
end
end
end)
end
--Events
R_Event.OnClientEvent:connect(function(action,args)
if action == "NewChar" then
CurrentPlayingAnimation = nil
for i,v in pairs(LoadedAnimations) do
v[1] = nil
end
end
end)
warn('INITIALIZATION4..')
MPS.PromptGamePassPurchaseFinished:connect(function(plr,id,purchased)
for i,v in pairs(AccessoriesMod) do
if id == v.GPId then
local frame = GamepassCache[id]
if frame and frame ~= nil then
frame.TextFrame.TextButton.Text = "Equip"
end
break
end
end
for i,v in pairs(PurchaseableMod) do
if v.id == id then
local frame = GamepassCache[id]
if frame and frame ~= nil then
frame.TextFrame.TextButton.Text = "Equip"
end
break
end
end
end)
--Misc
for i,v in pairs(Buttons) do
v.Button.MouseButton1Down:connect(function()
for i,v in pairs(v.FramesToClose) do
v.Visible = false
end
if v.Type == "Toggle" then
v.ActionFrame.Visible = not v.ActionFrame.Visible
elseif v.Type == "Close" then
v.ActionFrame.Visible = false
elseif v.Type == "Open" then
v.ActionFrame.Visible = true
end
end)
end
for i,v in pairs(AnimationsFrame.ScrollingFrame:GetChildren()) do
if v:IsA("Frame") then
v.Frame.TextButton.MouseButton1Down:connect(function()
AnimatePlayer(v.Frame.TextButton.Text)
end)
end
end
AccessorieRemove.MouseButton1Down:Connect(function()
Fire("AccessorieDelete", {Type = "All"})
end)
SaveOutfit.MouseButton1Down:Connect(function()
Fire('SaveOutfit', {Type = "All"})
end)
if EnableCustom.Value == true then
SaveOutfit.Text = "SAVE OUTFIT (TRUE)"
else
SaveOutfit.Text = "SAVE OUTFIT (FALSE)"
end
EnableCustom.Changed:Connect(function()
if EnableCustom.Value == true then
SaveOutfit.Text = "SAVE OUTFIT (TRUE)"
else
SaveOutfit.Text = "SAVE OUTFIT (FALSE)"
end
end)
I really can’t see why it’s taking this long to run through.
EDIT: By using prints it seems that the delay is coming heavily from the for i,v in pairs(PurchaseableMod) do