How to make it so that all of my buttons don't lag my game because of this

Hello, so I am scripting a tycoon and for all the button’s If the player is close to the button, then I want it to show what the button will unlock lightly transparent. But it lags my game down to 27 FPS.

Script:

		RunService.Heartbeat:Connect(function()
			local Distance = (TouchPart.Position - character.PrimaryPart.Position).Magnitude

			if Distance <= 8 then
				for _, v in pairs(TycoonFolder:GetDescendants()) do
					if v:GetAttribute("UnlockedBy") == ButtonUnlock then
						Unlock.FadeAnim(v,.5)
					end
				end
			else
				for _, v in pairs(TycoonFolder:GetDescendants()) do
					if v:GetAttribute("UnlockedBy") == ButtonUnlock then
						for _, part in pairs(v:GetChildren()) do
							if part:IsA("BasePart") then
								if part.Transparency == 1 then
									break
								else
									Unlock.FadeAnim(v,1)
								end
							end
						end
					end
				end
			end
		end)
RunService.Heartbeat:Connect(function()

Add a debounce, the ‘FadeAnim’ code is going to be ran every frame while the distance is less than 8.

Can you show me how I would do that

Doing this every heartbeat seems an extremely inefficient way of checking the proximity of a player character. Why not put it into a while loop and check every 1 second or 1/2 second. Nobody is going to notice a few frames delay in it changing the button. They will however notice your game running slow.

I tried using that method but it still made frames drop. Not just for me but for my friends too.

Put all the buttons into a folder and for loop through the folder instead.
Make sure you’re doing this locally and not on the server side, this will help reduce stress on the server and rely more on the client.
Don’t loop check so often if you have no need to loop that often. You can also try stopping the check if the player is not moving.
If the buttons are in a certain area, check if the player is in the area first, if they aren’t, just don’t do anything. If they are, start checks for the distance and so on and so forth. This is to prevent unneccessary computation for distance and such if there is no need to.

Have you validated how many items you are checking in your GetDescendants array? Is it 100?, 1000?, 100000?
Structuring your workspace logically and adding the items to be changed to a single folder as Children only and a subsequent change to GetChildren in place of GetDescendants should improve things.

I will try these techniques right now

Um, I don’t understand on how I should do this can you give me a sample maybe? Because I tried looping through all of the buttons and it isn’t working :confused: