Hello, I’ve been working on a script to make it easier to add effects to gui objects and to simplify it. It works fine, all of the events. Ive had a really hard and somewhat frustrating time figuring out how it lags. I tried using RunService.Heartbeat and while loops but I don’t know if there’s a better answer.
When the player join,s the code searches all descendants of the playerGui(not including stuff like chat, mobile controls, etc.) for object values determining what effect it gives. Then when the player hovers over or leaves or clicks the GuiObject in the tables where the parts are located with its data for tweens, properties, etc. It does it.
EDIT: I’m not sure if I was clear on this so here. All objects that ave a value are put inside the table tableEffects to prevent searching through all of playerGui to get updates, with extra data for the parts in extraTableInfo. Currently I search through that table of objects for events
Now for the issue:
Ive had a hard time with some of the events causing lag when the player hovers over some objects, leaves, and clicks. I added denounces to make that event happen only once per updateTime, but it isn’t enough. Its come a long way from basically not playable, to its current state. Im not 100% on this, but I’m pretty sure it causes some crashes on mobile atm. I want to get help on this because my end goal is to publish this script to help other devs who struggle with making gui elements to make their lives easier, but I don’t want to publish it if its just going to lag their game. Any suggestions on how I can make it less laggy are appreciated, even on how I can make the instructions more clear. Ive spent >2 days trying to optimize it and recently I’ve been struggling/burnt out so I’m coming here for some help.
--[[
-- Created by grif_0
-- Gui Elements V1.0
========== LABELS ==========
When inserting an element to a label, insert an ObjectValue into the label, and
_buttonMove - Button grows when hovered over and left
_labelHover - Label will hover slightly up and down
_labelInfo - Displays a textlabel at the mouse with the info inside of a string value inside the value
_buttonClickBL - doesnt play a click when the button is clicked, and doButtonClick = true. ONLY works inside of a TextButton or ImageButton.
_buttonHoverBL - doesnt play a click when the button is clicked, and doButtonHover = true. ONLY works inside of a TextButton or ImageButton.
doButtonClick - determines whether you want buttons to make a click sound when clicked.
doButtonHover - determines whether buttons make a sound when you enter and make a sound.
for _labelHover, you can chose how high it hovers up and down by putting a Module named '_Config' inside the ObjectValue, with a table inside named:
module.Config = {
["Position"] = UDim2.new(); amount ADDED to the current position
["EasingDirection"] = EasingDirection;
["EasingStyle"] = EasingStyle;
["Time"] = Time}
The default values are as following:
["Position"] = UDim2.new(0,0,guiPart.Parent.AbsoluteSize.Y * .05 / guiPart.Parent.AbsoluteSize.Y,0)
["EasingDirection"] = Enum.EasingDirection.InOut;
["EasingStyle"] = Enum.EasingStyle.Circular;
["Time"] = 5
["Override"] = true -- will always be true
for _buttonMove, you are able to determine how bix exactily the buttons grow, by putting a module named '_Config' inside of the ObjectValue, with a table inside named:
module.Config = {
["Position"] = UDim2.new(); -- amount ADDED to the current position
["EasingStyle"] = EasingStyle;
["EasingDirection"] = EasingDirection;
["Time"] = Time} }
the default values are as following:
["Position"] = UDim2.new(guiPart.Size.X.Scale/4,0,0,0)
["EasingDirection"] = Enum.EasingStyle.Sine;
["EasingStyle"] = Enum.EasingDirection.Out;
["Time"] = .5
for _labelInfo, the textbox scales automatically to the size of the text. To change the style of the text label, then put a module named '_Config' inside of the Object value, with a table named 'Config'. If no module is found then it will set the style
found in 'labelInfoTable'. You can change the style buy adding the Property name inside the index of the table, and the value to the value of the table. The defaults are as shown:
["BackgroundTransparency"] = .5;
["BorderSizePixel"] = 0;
["BackgroundColor3"] = Color3.fromRGB(125,125,125);
]]
local updateTime = .05
local doButtonClick = true -- determines if clicking buttons makes a sound
local doButtonHover = true -- determines if hovering over buttons makes a sound
local labelInfoTable = {
["BackgroundTransparency"] = .75;
["BorderSizePixel"] = 0;
}
--[[
Dont edit anything below unless you know what your doing
--------------------------------------------------------------------------------------------------------------------------------------------------]]
local player = game.Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local mouse = player:GetMouse()
local soundService = game:GetService("SoundService")
local tableEffects = {
["_buttonMove"] = {};
["_labelHover"] = {};
["_labelInfo"] = {};
["_buttonClickBL"] = {};
["_buttonHoverBL"] = {};
["_buttonSounds"] = {}
}
local extraTableInfo = {
["_buttonMove"] = {};
["_labelHover"] = {};
["_labelInfo"] = {};
["_buttonHover"] = {};
}
local labelInfoDefault = {
["Text"] = " ";
["BackgroundColor3"] = Color3.fromRGB(125,125,125);
["BackgroundTransparency"] = .5;
["BorderColor3"] = Color3.fromRGB(0,0,0);
["BorderMode"] = Enum.BorderMode.Outline;
["BorderSizePixel"] = labelInfoTable["BorderSizePixlel"];
["Font"] = Enum.Font.Arial;
["TextColor3"] = Color3.fromRGB(0,0,0);
["TextStrokeColor3"] = Color3.fromRGB(0,0,0);
["TextStrokeTransparency"] = 1;
["TextTransparency"] = 0;
["TextXAlignment"] = Enum.TextXAlignment.Left;
["TextYAlignment"] = Enum.TextYAlignment.Bottom;
["TextSize"] = 10
}
local debounce1 = false
local debounce2 = false
local debounce3 = false
local debounce4 = false
local finished = false
local doLabelInfo = false
function checkDescendants(v)
if v:IsA("GuiButton") then
if not v:IsDescendantOf(playerGui:WaitForChild("BubbleChat")) and not v:IsDescendantOf(playerGui:WaitForChild("Chat")) and not v:IsDescendantOf(playerGui:WaitForChild("Freecam")) then
if playerGui:FindFirstChild("TouchGui") then
if not v:IsDescendantOf(playerGui:WaitForChild("TouchGui")) then
tableEffects["_buttonSounds"][#tableEffects["_buttonSounds"]+1] = v
extraTableInfo["_buttonHover"][v] = {["Deb"] = false}
end
else
tableEffects["_buttonSounds"][#tableEffects["_buttonSounds"]+1] = v
extraTableInfo["_buttonHover"][v] = {["Deb"] = false}
end
end
end
if v:FindFirstChild("_buttonMove") then
tableEffects["_buttonMove"][#tableEffects["_buttonMove"]+1] = v
local size = require(v:FindFirstChild("_buttonMove"):FindFirstChild("_Config"))
extraTableInfo["_buttonMove"][v] = {["Deb"] = false;["Close"] = v.Size;["Open"] = (size.Config["Position"] or UDim2.new(v.Size.X.Scale/4,0,0,0)) + v.Size;["EasingStyle"] = size.Config["EasingStyle"] or Enum.EasingStyle.Sine;["EasingDirection"] = size.Config["EasingDirection"] or Enum.EasingDirection.Out;["Time"] = size.Config["Time"] or .5}
v:FindFirstChild("_buttonMove"):Destroy()
end
if v:FindFirstChild("_labelHover") then
tableEffects["_labelHover"][#tableEffects["_labelHover"]+1] = v
local size = require(v:FindFirstChild("_labelHover"):FindFirstChild("_Config"))
extraTableInfo["_labelHover"][v] = {["Position"] = v.Position + (size.Config["Position"] or UDim2.new(0,0,v.Parent.AbsoluteSize.Y * .05 / v.Parent.AbsoluteSize.Y,0));["EasingStyle"] = size.Config["EasingStyle"] or Enum.EasingStyle.Circular;["EasingDirection"] = size.Config["EasingDirection"] or Enum.EasingDirection.InOut;["Time"] = size.Config["Time"] or 5}
v:FindFirstChild("_labelHover"):Destroy()
end
if v:FindFirstChild("_labelInfo") then
tableEffects["_labelInfo"][#tableEffects["_labelInfo"]+1] = v
local module = require(v:FindFirstChild("_labelInfo"):FindFirstChild("_Config"))
extraTableInfo["_labelInfo"][v] = {["Text"] = " ";["BackgroundColor3"] = " ";["BackgroundTransparency"] = " ";["BorderColor3"] = " ";["BorderMode"] = " ";["BorderSizePixel"] = " ";["Font"] = " ";["TextColor3"] = " ";["TextStrokeColor3"] = " ";["TextStrokeTransparency"] = " ";["TextTransparency"] = " ";["TextXAlignment"] = " ";["TextYAlignment"] = " ";["TextSize"] = " ";}
for i,_ in pairs(extraTableInfo["_labelInfo"][v]) do
if module.Config[i] ~= nil then
extraTableInfo["_labelInfo"][v][i] = module.Config[i]
elseif labelInfoTable[i] ~= nil then
extraTableInfo["_labelInfo"][v][i] = labelInfoTable[i]
else
extraTableInfo["_labelInfo"][v][i] = labelInfoDefault[i]
end
end
v:FindFirstChild("_labelInfo"):Destroy()
end
if v:FindFirstChild("_buttonClickBL") then
tableEffects["_buttonClickBL"][#tableEffects["_buttonClickBL"]+1] = v
v:FindFirstChild("_buttonClickBL"):Destroy()
end
if v:FindFirstChild("_buttonHoverBL") then
tableEffects["_buttonHoverBL"][#tableEffects["_buttonHoverBL"]+1] = v
v:FindFirstChild("_buttonHoverBL"):Destroy()
end
end
for i,v in pairs(playerGui:GetDescendants()) do
checkDescendants(v)
end
finished = true
function mouseHoverSound()
end
function buttonMove(guiPart,direction)
debounce3 = true
if direction == true then
extraTableInfo["_buttonMove"][guiPart]["Deb"] = true
local size = extraTableInfo["_buttonMove"][guiPart]
guiPart:TweenSize(size["Open"],size["EasingDirection"],size["EasingStyle"],size["Time"],true)
elseif direction == false then
extraTableInfo["_buttonMove"][guiPart]["Deb"] = false
local size = extraTableInfo["_buttonMove"][guiPart]
guiPart:TweenSize(size["Close"],size["EasingDirection"],size["EasingStyle"],size["Time"],true)
end
debounce3 = false
end
function labelInfo(guiPart,visible)
if visible == true then
if playerGui:FindFirstChild("_labelInfo") then
playerGui:FindFirstChild("_labelInfo"):Destroy()
end
doLabelInfo = true
local gui = Instance.new("ScreenGui")
gui.Parent = playerGui
gui.Name = "_labelInfo"
gui.ResetOnSpawn = false
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(.1,0,.25,0)
textLabel.Parent = gui
textLabel.AnchorPoint = Vector2.new(0,1)
textLabel.TextWrapped = true
textLabel.Position = UDim2.new(0,mouse.X + 5,0,mouse.Y - 5)
for i,v in pairs(extraTableInfo["_labelInfo"][guiPart]) do
textLabel[i] = v
end
local size = game:GetService("TextService"):GetTextSize(extraTableInfo["_labelInfo"][guiPart]["Text"],extraTableInfo["_labelInfo"][guiPart]["TextSize"],extraTableInfo["_labelInfo"][guiPart]["Font"],textLabel.AbsoluteSize)
textLabel.Size = UDim2.new(0,size.X,0,size.Y)
elseif visible == false then
doLabelInfo = false
if playerGui:FindFirstChild("_labelInfo") then
playerGui:FindFirstChild("_labelInfo"):Destroy()
end
end
end
for i,v in pairs(tableEffects["_labelHover"]) do
local size = extraTableInfo["_labelHover"][v]
game:GetService("TweenService"):Create(v,TweenInfo.new(size["Time"],size["EasingStyle"],size["EasingDirection"],math.huge,true,0),{Position = extraTableInfo["_labelHover"][v]["Position"]}):Play()
end
while wait(updateTime) do
if finished == true then
local deb1 = false
local deb1 = false
local deb2 = false
local deb3 = false
local deb4 = false
for i,tab in pairs(tableEffects) do
for i,v in pairs(tab) do
if v:IsA("GuiObject") then
v.MouseLeave:Connect(function()
if table.find(tableEffects["_buttonSounds"],v) and extraTableInfo["_buttonHover"][v]["Deb"] == true then
extraTableInfo["_buttonHover"][v]["Deb"] = false
end
if table.find(tableEffects["_buttonMove"],v) and debounce3 == false and extraTableInfo["_buttonMove"][v]["Deb"] == true and deb3 == false then
deb3 = true
buttonMove(v,false)
end
if table.find(tableEffects["_labelInfo"],v) and debounce4 == true and deb4 == false and playerGui:FindFirstChild("_labelInfo") then
debounce4 = false
deb4 = true
labelInfo(v,false)
end
end)
v.MouseEnter:Connect(function()
if table.find(tableEffects["_buttonSounds"],v) and not table.find(tableEffects["_buttonHoverBL"],v) and extraTableInfo["_buttonHover"][v]["Deb"] == false and doButtonHover == true and debounce1 == false and deb1 == false then
extraTableInfo["_buttonHover"][v]["Deb"] = true
deb1 = true
debounce1 = true
soundService.ui_hover1:Play()
debounce1 = false
end
if table.find(tableEffects["_buttonMove"],v) and debounce3 == false and extraTableInfo["_buttonMove"][v]["Deb"] == false and deb3 == false then
deb3 = true
buttonMove(v,true)
end
if table.find(tableEffects["_labelInfo"],v) and debounce4 == false and deb4 == false and not playerGui:FindFirstChild("_labelInfo") then
debounce4 = true
deb4 = true
labelInfo(v,true)
end
end)
end
if v:IsA("GuiButton") then
v.MouseButton1Click:Connect(function()
if table.find(tableEffects["_buttonSounds"],v) and not table.find(tableEffects["_buttonClickBL"],v) and doButtonClick == true and debounce2 == false then
debounce2 = true
soundService.ui_button1:Play()
debounce2 = false
end
end)
end
end
end
playerGui.DescendantAdded:Connect(function(part)
for i,v in pairs(part:GetDescendants()) do
checkDescendants(v)
end
end)
if doLabelInfo == true then
local textFrame = playerGui:WaitForChild("_labelInfo"):WaitForChild("TextLabel")
textFrame.Position = UDim2.new(0,mouse.X + 5,0,mouse.Y - 5)
end
end
end