When you’re unloading you’re not removing the old position CFrame, you have both the void and ‘default’ in the same table.
Update the old CFrame when unloading (currently you’re pushing a new one)
When you’re unloading you’re not removing the old position CFrame, you have both the void and ‘default’ in the same table.
Update the old CFrame when unloading (currently you’re pushing a new one)
As i said i tried working with attributes, attribute stored original cframe and it was static i checked, but again, it unloaded the part and never loaded it back. But I will try
What happens is that when load and unload the same object before a update the table is not cleared, this makes so there’s 2 registers of the same part before the update.
Load → Adds the position and part to the table
Unload → Also adds the unload position and part to the table
edit: you should check in the unload function, to see if the part was added already to the table and if so edit the cframe to the void one
like so?
for i, movingPart in ipairs(self.MovingParts) do
if movingPart == Part then
self.MovingCFrames[i] = self.unloadCFrame
return
end
end
no worky
Ok we have some movement right here, now both parts disappear:
-- Created by 1Xayd1
local RenderCache = {}
RenderCache.__index = RenderCache
export type RenderCacheType = {
MovingParts: {BasePart},
MovingCFrames: {CFrame},
OriginalCFrames: {CFrame},
unloadCFrame: CFrame,
Updating: boolean,
new: () -> RenderCacheType,
Register: (self: RenderCacheType, array: {BasePart}) -> (),
Update: (self: RenderCacheType) -> (),
Load: (self: RenderCacheType, Part: BasePart) -> (),
Unload: (self: RenderCacheType, Part: BasePart) -> ()
}
function RenderCache.new(): RenderCacheType
local self = setmetatable({}, RenderCache)
self.MovingParts = table.create(10_000)
self.MovingCFrames = table.create(10_000)
self.OriginalCFrames = table.create(10_000)
self.unloadCFrame = CFrame.new(2^24, 2^24, 2^24)
self.Updating = false
return self
end
function RenderCache:Register(array: {BasePart})
for _, part in ipairs(array) do
table.insert(self.OriginalCFrames, part.CFrame)
end
end
function RenderCache:Update()
if self.Updating then warn("Tried to update while updating, skipping.") return end
self.Updating = true
workspace:BulkMoveTo(self.MovingParts, self.MovingCFrames, Enum.BulkMoveMode.FireCFrameChanged)
table.clear(self.MovingParts)
table.clear(self.MovingCFrames)
self.Updating = false
end
function RenderCache:Load(Part: BasePart)
local index = table.find(self.MovingParts, Part)
if index then
self.MovingCFrames[index] = self.OriginalCFrames[index]
else
warn("Part not registered in cache!")
return
end
table.insert(self.MovingParts, Part)
end
function RenderCache:Unload(Part: BasePart)
local index = table.find(self.MovingParts, Part)
if index then
self.MovingCFrames[index] = self.unloadCFrame
end
table.insert(self.MovingParts, Part)
table.insert(self.MovingCFrames, self.unloadCFrame)
end
return RenderCache
Lemme add queue like in Object Cache
Queue didnt help either:
-- Created by 1Xayd1
local RenderCache = {}
RenderCache.__index = RenderCache
export type RenderCacheType = {
MovingParts: {BasePart},
MovingCFrames: {CFrame},
RegisteredCFrames: {[BasePart]: CFrame},
unloadCFrame: CFrame,
Updating: boolean,
LoadQueue: {BasePart},
UnloadQueue: {BasePart},
new: () -> RenderCacheType,
Register: (self: RenderCacheType, array: {BasePart}) -> (),
Update: (self: RenderCacheType) -> (),
Load: (self: RenderCacheType, Part: BasePart) -> (),
Unload: (self: RenderCacheType, Part: BasePart) -> ()
}
function RenderCache.new(): RenderCacheType
local self = setmetatable({}, RenderCache)
self.MovingParts = table.create(10_000)
self.MovingCFrames = table.create(10_000)
self.RegisteredCFrames = {}
self.unloadCFrame = CFrame.new(2^24, 2^24, 2^24)
self.Updating = false
self.LoadQueue = {}
self.UnloadQueue = {}
return self
end
function RenderCache:Register(array: {BasePart})
for _, part in ipairs(array) do
self.RegisteredCFrames[part] = part.CFrame
end
end
function RenderCache:Update()
if self.Updating then
warn("Tried to update while updating, skipping.")
return
end
self.Updating = true
for _, part in ipairs(self.LoadQueue) do
table.insert(self.MovingParts, part)
table.insert(self.MovingCFrames, self.RegisteredCFrames[part])
end
for _, part in ipairs(self.UnloadQueue) do
table.insert(self.MovingParts, part)
table.insert(self.MovingCFrames, self.unloadCFrame)
end
workspace:BulkMoveTo(self.MovingParts, self.MovingCFrames, Enum.BulkMoveMode.FireCFrameChanged)
table.clear(self.MovingParts)
table.clear(self.MovingCFrames)
table.clear(self.LoadQueue)
table.clear(self.UnloadQueue)
self.Updating = false
end
function RenderCache:Load(Part: BasePart)
if not self.RegisteredCFrames[Part] then
warn("Part not registered in cache!")
return
elseif self.Updating then
warn("Cannot load | unload objects while updating.")
return
end
table.insert(self.LoadQueue, Part)
end
function RenderCache:Unload(Part: BasePart)
if not self.RegisteredCFrames[Part] then
warn("Part not registered in cache!")
return
elseif self.Updating then
warn("Cannot load | unload objects while updating.")
return
end
table.insert(self.UnloadQueue, Part)
end
return RenderCache
The self.Updating
logic doesnt seem required in the given code. Since you are doing the update in a single frame (without yielding) anyway other code logic wont even notice the change.
Also, I was unable to reproduce the bug you were dealing with.
Here is a script Load()
ing and Unload()
ing a part every one fourth of a second:
Please help me understand :D
how… Give me that place right now!
local RenderCache = require(script.Parent)
local GamingCache = RenderCache.new()
local Part = workspace.Part
GamingCache:Register({Part})
game:GetService("RunService").Stepped:Connect(function()
GamingCache:Update()
end)
while true do
task.wait(1 / 4)
GamingCache:Unload(Part)
task.wait(1 / 4)
GamingCache:Load(Part)
end
Just doing this with the first ever modulescript code you attached in this post.
Seems to work just fine.
I update the cache every time i unload or load the part
not every frame, hmmmm
wait actually what the hell its working
I have no idea why though, releasing the module today!
Yes this is what I was asking about!
For example if you do something like this:
while true do
task.wait(1 / 4)
Cache:Unload(Part)
task.wait(1 / 4)
Cache:Load(Part)
Cache:Update()
end
The part will appear if so the part never dissapeared. (Yes! Even with the delays in between since thats how update() works)
The issue is here, you have a queue which gets processed every time :Update()
is called (which uses FIFO logic but I will not go over that).
If you were to for example do
Cache:Unload(Part)
Cache:Load(Part)
Cache:Update()
The part would appear as it had never loaded out.
Which is OK!
But could cause confusion to where to use update() with, connecting it to an event like RenderStepped gives the developer an ease of use.
This is a performance concern too, what if thousands of parts load out and load in at the same time?
As far as I know BulkMoveTo() function does not check for duplicates in the table you provided it with.
This is not how i used module as you provided it. It was exactly the same as your script, so its not my fault. And I am not so dumb for you to explain it like this Edit: it was roblox’s issue
Thats how I usually explain stuff sorry you thought that way
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.