There are tweens and particle emitters all across the map (there are over 1000).
Obviously this has a large effect on CPU, so my plan is to only turn on these effects when the player is near them.
What is the best way to do that in Roblox?
I know that I can use magnitude to see how far any part is away from the player.
local distance = (HumanoidRootPart.Position - OtherPart.Position).magnitude
What I’m not sure about is how to check 1000’s of parts in an optimal way every few seconds.
My best guess (and I haven’t tried this yet) is to create a table that has a reference to all tweens and particle emitters, and then every 5 seconds scan the table to switch off effects outside of X distance and switch on effects near the player.
I guess I could dynamically build that table when the player joins the game by looping through all parts in the workspace adding a reference to the part in the table if it is a tween or a particle emitter.
Is that the right way? Or is there something better already built in to Roblox?
I know I can probably work this out but just in case you feel like sharing how would I pass the current player and the radius to check into that function?
No worries if you don’t have time - and thanks so much this is already a huge help.
Just found this. I think it might be part of the answer?
local function CreateRegion3FromLocAndSize(Position, Size)
local SizeOffset = Size/2
local Point1 = Position - SizeOffset
local Point2 = Position + SizeOffset
return Region3.new(Point1, Point2)
end
local folderContainingAllObjects = workspace.ParticleEmitterFolder
local radius = 10
while wait(1) do
for _, v in pairs(folderContainingAllObjects:GetDescendants()) do
if v:IsA("ParticleEmitter") then
v.Enabled = false
end
end
local anchorCF = localPlayer.Character.HumanoidRootPart.CFrame
local r1 = anchorCF * CFrame.new(radius, radius, radius)
local r2 = anchorCF * CFrame.new(radius, radius, radius):Inverse()
local region = Region3.new(
Vector3.new(math.min(r1.X, r2.X), math.min(r1.Y, r2.Y), math.min(r1.Z, r2.Z),
Vector3.new(math.max(r1.X, r2.X), math.max(r1.Y, r2.Y), math.max(r1.Z, r2.Z)
)
local parts = workspace:FindPartsInRegion3WithWhiteList(region, {folderContainingAllObjects})
for _, aPartInThisRadius in pairs(parts) do
local particleEmitter = aPartInThisRadius.ParticleEmitter -- you will have to change this to how you need it
particleEmitter.Enabled = true
end
end
the reason i did the Region3 like that was because it usually wants it given from corner to corner.
Good luck on your project!
local folderContainingAllObjects = workspace.ParticleEmitterFolder
local radius = 50
while wait(1) do
for _, v in pairs(folderContainingAllObjects:GetDescendants()) do
if v:IsA("ParticleEmitter") then
v.Enabled = false
end
local distance = (localPlayer.Character.HumanoidRootPart.Position - v.Position).magnitude
if distance < radius then
v.Enabled = true
end
end
end
Just trying to wrap my head around what workspace:FindPartsInRegion3WithWhiteList brings to the party?
Oops it didnt see this reply lol
This will work perfect, but the only problem is that using .Magnitude is really expensive and uses a lot of computing power in Roblox, that’s why I was suggesting using Region3, but this should work just fine.
I wasn’t able to get the region3 version to work so I went with my noob version. It doesn’t seem to be having an impact on the CPU but I’ll circle back to the better way when I have more time.
What was happening with Region3 was some kind of CPU spike and Roblox studio froze. I guess it’s something to do with me using a tags plugin collection rather than a folder.
I’ll probably circle back to this when there are a 2000+ effects in the game. The noob version is working pretty well for the moment though.