is it ever ok to do something like this? or is this a better solution
local RunService = game:GetService("RunService")
local Collectionservice = game:GetService("CollectionService")
local play = game.ReplicatedStorage.Events.Playsound2
local stop = game.ReplicatedStorage.Events.StopSound
function OnTouch(b)
if a.AbsolutePosition.X >= b.AbsolutePosition.X and a.AbsolutePosition.X <= b.AbsolutePosition.X+b.AbsoluteSize.X then
if b.UIStroke.Enabled == true then return end
local velocity = b.assets.Velocity.Value
b.UIStroke.Enabled = true
else
b.UIStroke.Enabled = false
end
end
RunService.RenderStepped:Connect(function()
local data = game.CollectionService:GetTagged("regions")
for i = 1,#data do local v = data[i]
coroutine.wrap(OnTouch)(v)
end
end)
especially when collection service tags reach ~700?
its gets laggy
Use a global array instead of running GetTagged everytime. Most of the memory usage is very likely coming from creating a new table every frame. This could look like:
local RegionList = CollectionService:GetTagged("Region")
local function OnRegionAdded(Object)
table.insert(RegionList, Object)
end
local function OnRegionRemoved(Object)
table.remove(RegionList, table.find(RegionList, Object))
end
CollectionService:GetInstanceAddedSignal("Region"):Connect(OnRegionAdded)
CollectionService:GetInstanceRemovedSignal("Region"):Connect(OnRegionRemoved)
I would say to use RunService:BindToRenderStep, as you can control in what order the callback is ran in relation to other engine loops. For example, since your regions are checking for GUI state, you can bind to Enum.RenderPriority.Input.Value + 1 (Right after input was registered) to be more precise.
Use a generalized loop, and if OnTouch is not planned to contain any yielding logic, don’t even wrap it in a coroutine. If it is, however, use task.spawn instead, as coroutine.wrap obscures error messages making debugging hard.
Like you would with other connections, except you are passing the callback to a method and not a signal.
local function OnRenderStep()
for _, Region in RegionList do
OnTouch(Region)
end
end
RunService:BindToRenderStep("CheckRegions", Enum.RenderPriority.Input.Value + 1, OnRenderStep)
my performance increased from 16 to 32fps the song plays great at ~40-50 fps but for like chorus, it drops again and the script runs ~32 memory again. maybe i still have too many notes in one chunk
If it is just looping through all the UI elements which is causing the lag, you could implement some kind of partitioning system where UI elements are grouped together based on their location. You would only need to loop through the partition where the line actually is, reducing the amount of time it takes.
Also, I’m not super certain on the internal workings of UIStroke, but it might take less memory to just have a few instances of UIStroke. As the line moves, you reparent them to the individual notes.
i have, ive created a render system but i think even that is flawed, ima bring up an auto save to find it if i can. but it renders up to 700+ notes in one screen out of the 10k notes in total
for i, frame in pairs(game.CollectionService:GetTagged("Chunk")) do
local playerhead = frame.Parent.Parent.DragableFrame
local collectionservice = game:GetService("CollectionService")
if frame:IsDescendantOf(script.Parent) then
local id = tostring(frame.Parent.Parent.Parent.Parent.ID.Value..frame.Name)
local guiInset = game:GetService("GuiService"):GetGuiInset()
local function isInScreen()
local pos = frame.AbsolutePosition + guiInset
return pos.X + frame.AbsoluteSize.X <= frame.Parent.Parent.AbsolutePosition.X+frame.Parent.Parent.AbsoluteSize.X and pos.X >= -frame.Parent.Parent.AbsoluteSize.X
end
frame.Parent.Parent.Octaves.DescendantAdded:Connect(function(child)
task.wait()
if not game.CollectionService:HasTag(child,"notes") then return end
if child.AbsolutePosition.X >= frame.AbsolutePosition.X and child.AbsolutePosition.X <= frame.AbsolutePosition.X+frame.AbsoluteSize.X then
collectionservice:AddTag(child,id)
child.assets.Chunk.Value = frame
if isInScreen() then
collectionservice:AddTag(child,"regions")
child.Visible = true
else
collectionservice:RemoveTag(child,"regions")
child.Visible = false
child.MakeGUIDraggable.Enabled = false
child.MakeGUICopyable.Enabled = false
end
end
end)
frame.Parent.Parent.Octaves.DescendantRemoving:Connect(function(child)
if not game.CollectionService:HasTag(child,"notes") then return end
if child.AbsolutePosition.X >= frame.AbsolutePosition.X and child.AbsolutePosition.X <= frame.AbsolutePosition.X+frame.AbsoluteSize.X then
collectionservice:RemoveTag(child,id)
end
end)
frame.Parent.Parent:GetPropertyChangedSignal("CanvasPosition"):Connect(function()
wait()
if isInScreen() then
if frame.rendered.Value == true then return end
frame.rendered.Value = true
frame.BackgroundColor3 = Color3.new(1, 1, 1)
for i, v in pairs(collectionservice:GetTagged(id)) do
collectionservice:AddTag(v,"regions")
v.Visible = true
end
else
if frame.rendered.Value == false then return end
frame.rendered.Value = false
frame.BackgroundColor3 = Color3.new(0.333333, 0.333333, 0.498039)
for i, v in pairs(collectionservice:GetTagged(id)) do
collectionservice:RemoveTag(v,"regions")
v.Visible = false
v.MakeGUIDraggable.Enabled = false
v.MakeGUICopyable.Enabled = false
end
end
end)
end
end
and there are multiple of these running per piano roll. and each piano roll has about ~256 renderframes each the size of the screen
wait no it wasnt my render system, it was accually my tween sounds, every sounds played tweens its volume to 0 befor destroyed. i did this for a fading effect but too many tweens lag my pc