Whenever my parts are far away (around 256+ on any axis), they destroy for the player locally for some reason… not sure why this happens. I have a small solution which is just :Clone() the parts into workspace in a LocalScript but this is more of a temporary solution.
local Menu = workspace:WaitForChild("Menu")
CameraPart:Clone().Parent = Menu
Showcase:Clone().Parent = workspace
Are there any ways I can improve the script to make it more efficient or counter this “bug”?
Unlike what @AkroThorn suggests, I would advise against disabling StreamingEnabled as a solution. It will be much better to keep StreamingEnabled on. In my experience it results in better programming practices if you learn to work with it, and it will result in better perf and memory usage.
You generally want your game to be able to handle StreamingEnabled without keeping the instance(s) around except in really specific cases where it really makes sense to keep those things around. For some things, you can place them into a model and set the ModelStreamingMode, however you don’t want objects to persist at all if you can help it.
This means using WaitForChild for objects with static, known paths, or using events like ChildAdded, or often even better, using CollectionService & adding special tags to your instances so that you can easily detect when those objects load/unload and perform code changes.
local RunService = game:GetService("RunService")
local random = Random.new(tick())
local heartbeatCount = 0
local flickerSources = {}
-- Detect tagged parts streaming in or out
if workspace.StreamingEnabled then
CollectionService:GetInstanceAddedSignal("FlickerLightSource"):Connect(function(light)
flickerSources[light] = true
end)
CollectionService:GetInstanceRemovedSignal("FlickerLightSource"):Connect(function(light)
flickerSources[light] = nil
end)
end
-- Flicker loop
RunService.Heartbeat:Connect(function()
heartbeatCount += 1
if heartbeatCount > 5 then
heartbeatCount = 0
for light, _ in pairs(flickerSources) do
light.Brightness = 8 + random:NextNumber(-0.4, 0.4)
end
end
end)```
CollectionService also opens up a whole programming paradigm that is pretty easy to work with and manage, which is similar to OOP. But, instead of making object classes and creating the object classes, you can make components which are like pieces or behaviours that describe what the object does or describe certain properties that the object can have (e.g. as attributes).
You can use components for singleton objects (unique objects of which only one exists), or you can use it for objects where many exist, even ones which are spawned/despawned by your game’s code naturally, and it works well in both cases. You can also use components to describe things that have generic behaviours, for example, things with health that can break for example.
A component is just a little behaviour that will attach to an instance that is tagged with that component’s tag, and can safely unattach itself when the instance is destroyed or the tag is removed.
Sleitnick has made a cool little module for Components that I often use in my projects, for example with Knit code. Component | RbxUtil
Alrighty, thank you for the replies! I will be looking into CollectionService since it does look a little complicated. (until I have CollectionService sorted I’ll be setting StreamingEnabled to false)
CollectionService itself thankfully isn’t too complicated on its own, really the relevant things areGetInstanceAddedSignal and GetInstanceRemovedSignal like @AkroThorn suggested. Components are just a more complicated but clean way to use CollectionService to do stuff.
Those two methods will return events that will get triggered when an instance with a specific tag you ask for is created or destroyed, which also includes from StreamingEnabled streaming the instance in or out too.