Hello, Im working on an inventory system and I have a script that detects when a player clicks on an item in their inventory (ScrollingFrame) and shows some information about that item. Right now I have a heartbeat function that runs checking if the player has clicked on an item: however Im for sure that this is not an optimized and appropriate way to do it. When I click the item while play testing everything works however a severe lag spike is caused every time I click. It would be great if anyone knows what other function I can try or a different way to script this.
Local script:
local Player = game.Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local InvFrame = script.Parent
local EquipFrame = script.Parent.Parent.EquipFrameSection
local DescriptionLabel = EquipFrame.Description
local NameLabel = EquipFrame.Title
local EquipButton = EquipFrame.EquipUseButton
local Clicked = false
local ItemPropertiesModule = require(ReplicatedStorage.Modules.ItemProperties)
local RarityColoursModule = require(ReplicatedStorage.Modules.ItemProperties.RarityColours)
local DataFolder = ReplicatedStorage.ReplicatedData:WaitForChild(Player.UserId)
local function Loop()
for i, v in pairs(InvFrame:GetChildren()) do
if v:IsA("ImageButton") then
print("found image")
local ItemName = ItemPropertiesModule[v.Name].Title
local Description = ItemPropertiesModule[v.Name].Description
v.MouseButton1Click:Connect(function()
print("clicked", ItemName)
if Clicked == false then
print("clicked false")
local RarityMod = ItemPropertiesModule[v.Name].Rarity
NameLabel.TextColor3 = (RarityColoursModule[RarityMod])
Clicked = true
EquipButton.Visible = true
NameLabel.Visible = true
DescriptionLabel.Visible = true
NameLabel.Text = ItemName
DescriptionLabel.Text = Description
elseif Clicked == true then
print("clicked ture")
Clicked = false
EquipButton.Visible = false
NameLabel.Visible = false
DescriptionLabel.Visible = false
end
end)
end
end
end
RunService.Heartbeat:Connect(Loop)
Here you appear to be doing a lot of tasks in one frame, firing this many tasks can overwhelm the Client causing Lag depending how long it takes to fire.
You could just use Changed or GetPropertyChangedSignal, Less Resources Used.
Yes I did that before but I changed it to heartbeat, the reason being is because it stops working when the item is destroyed in workspace (The one that the player can pick up). Im using datastore2 with a string value that saves the inventory in ReplicatedStorage. I used .Changed before but the function was firing and everything was printing but the other stuff in the mousebutton1click function was not working and I was incredibly confused. No visible errors in the output.
Holy. You are creating a bunch of connections every single heartbeat! No wonder it is lagging!!
Please remove it from the heartbeat and just call it once!
function OnClick(v)
print("clicked", ItemName)
if Clicked == false then
print("clicked false")
local RarityMod = ItemPropertiesModule[v.Name].Rarity
NameLabel.TextColor3 = (RarityColoursModule[RarityMod])
Clicked = true
EquipButton.Visible = true
NameLabel.Visible = true
DescriptionLabel.Visible = true
NameLabel.Text = ItemPropertiesModule[v.Name].Title
DescriptionLabel.Text = ItemPropertiesModule[v.Name].Description
elseif Clicked == true then
print("Clicked true")
Clicked = false
EquipButton.Visible = false
NameLabel.Visible = false
DescriptionLabel.Visible = false
end
end)
end
for i, v in pairs(InvFrame:GetChildren()) do
if v:IsA("ImageButton") then
print("found image")
v.MouseButton1Click:Connect(function()
OnClick(v)
end)
end
end
-- Then to account for new ones being added
InvFrame.ChildAdded:Connect(function(child)
child.MouseButton1Click:Connect(function()
OnClick(ItemProperties[child])
end)
end)
local Player = game.Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local InvFrame = script.Parent
local EquipFrame = script.Parent.Parent.EquipFrameSection
local DescriptionLabel = EquipFrame.Description
local NameLabel = EquipFrame.Title
local EquipButton = EquipFrame.EquipUseButton
local Clicked = false
local ItemPropertiesModule = require(ReplicatedStorage.Modules.ItemProperties)
local RarityColoursModule = require(ReplicatedStorage.Modules.ItemProperties.RarityColours)
local DataFolder = ReplicatedStorage.ReplicatedData:WaitForChild(Player.UserId)
local function OnClick(v)
local ItemName = ItemPropertiesModule[v.Name].Title
local Description = ItemPropertiesModule[v.Name].Description
if Clicked == false then
local RarityMod = ItemPropertiesModule[v.Name].Rarity
NameLabel.TextColor3 = (RarityColoursModule[RarityMod])
Clicked = true
EquipButton.Visible = true
NameLabel.Visible = true
DescriptionLabel.Visible = true
NameLabel.Text = ItemName
DescriptionLabel.Text = Description
elseif Clicked == true then
Clicked = false
EquipButton.Visible = false
NameLabel.Visible = false
DescriptionLabel.Visible = false
end
end
for i, v in pairs(InvFrame:GetChildren()) do
if v:IsA("ImageButton") then
v.MouseButton1Click:Connect(function()
OnClick(v)
end)
end
end
InvFrame.ChildAdded:Connect(function(child)
child.MouseButton1Click:Connect(function()
OnClick(ItemPropertiesModule[child])
end)
end)
InvFrame.ChildAdded:Connect(function(child)
child.MouseButton1Click:Connect(function()
if not child:IsA("ImageButton") then return end
OnClick(child)
end)
end)
edit: For people coming in the future, this my reply was a continuation of my previous reply, found here