So I got a problem trying to fix the lag but I don’t know any other way to get the results I need.
local function CheckCollisions()
for _, part in ipairs(Parts:GetDescendants()) do
if part:IsA("BasePart") then
for _, v in ipairs(workspace:GetDescendants()) do
if v:IsA("BasePart") then
local distance = (part.Position - v.Position).Magnitude
local speed = (part.AssemblyLinearVelocity - v.AssemblyLinearVelocity).Magnitude
if distance <= 5 and speed >= 10 then
Break(part)
end
end
end
end
end
end
RunService.Heartbeat:Connect(CheckCollisions)
You are entering this function on every heartbeat, that means this heavy search algorithm will continuously start every ~4ms. You need to wait for it to complete one iteration before starting the next iteration. This can be achieved using a debounce to prevent re-entry until an iteration has completed, or you can use the deltaTime parameter that is supplied to RunService.Heartbeat:Connect() and compare with a variable that stores startTime and currentTime to run the check at whatever frequency you find produces the least lag.
In this case it might be better to use an Octree so instead of looping through every descendant of workspace you only loop through the ones in the nearby sectors of part. This would not be a trivial thing to add.
Alternatively, you could try splitting up the workload with different actors (Assuming this runs on the server with a decent number of cores), but I’m convinced the bottleneck of having to re-enter serial execution every time you want to call Break would make it just perform worse.
As @MagmaBurnsV says. A more robust and efficient method of performing this sort of heavy part iteration would be to use an Octree, @Quenty made an excellent and efficient module for this, which has been expanded in the link @MagmaBurnsV provided.
Instead of tackling the herculean effort it takes to even understand what an octree is, let alone use one, try refining which parts you are even needing to iterate over in the first place.
It’d probably help if you tried explaning to us what you are even trying to accomplish. Any highly repetitive task that continously calls GetDescendants() is going to end up causing extreme lag no matter what you do.
Then just used the Touched event? No reason to recreate the wheel here.
If you’re having issues detecting which parts are touching, you could always just use GetPartsInPart() method of WorldRoot to determine which parts are intersecting (touching) the part you are monitoring.
for _, part in ipairs(Parts:GetDescendants()) do
if part:IsA("BasePart") then
part.Touched:Connect(function(hit)
local isFiltered = isFilteredCheck(castParams.FilterDescendantsInstances, hit)
if isFiltered == true then
Break(part)
end
end)
end
end
I also used GetTouchingParts:
for _, part in ipairs(Parts:GetDescendants()) do
if part:IsA("BasePart") then
RunService.Heartbeat:Connect(function()
local touchingParts = part:GetTouchingParts()
for i,v in pairs(touchingParts) do
local isFiltered = isFilteredCheck(castParams.FilterDescendantsInstances, v)
if isFiltered == true then
Break(part)
end
end
end)
end
end
What do you mean? Parts is a folder that is storing the parts for the model. I’m detecting if anything is hitting any part in the Parts folder, if so, break the part.