local Loadables = {workspace:GetDescendants(), StarterGui:GetDescendants(), SoundService:GetDescendants()}
for i = 1, #Loadables do
ContentProvider:PreloadAsync({Loadables[i]}) -- ERROR HERE
Loading.Text = i .. "/" .. #Loadables
end
workspace:GetDescendants() and other values in Loadables are tables, encapsulating Loading[i] in {} makes a table with a value which is another table but with the descendants.
local Loadables = {object:GetDescendants}
-- Loadables is something like {{a, b, c}}
print(typeof(Loadables[1])) --> table
local whatYouPassed = {Loadables[1]}
print(typeof(whatYouPassed[1])) --> table (of descendants)
local whatShoudBePassed = Loadables[1]
print(whatShoudBePassed} --> a
local Loadables = {workspace:GetDescendants(), StarterGui:GetDescendants(), SoundService:GetDescendants()}
for i = 1, #Loadables do
ContentProvider:PreloadAsync(Loadables[i])
Loading.Text = i .. "/" .. #Loadables
end
Still doesn’t work.
Remember that i
and #Loadables
are numbers so you have to call tostring
so it can concatonate with the /
string: Loading.Text = tostring(i) .. "/" .. tostring(#Loadables)
Also, you don’t need to call GetDescendants
because PreloadAsync iterates through all descendants for you I believe.
It only goes:
‘1/3’
‘2/3’
‘3/3’
It should have ALL the assets in game that it’s loading. There’s definately not just 3 assets
There are only three values in Loadables, each value is table which has several more values inside it. Remember, Loadables[i] contains the actual assets, Loadables contains tables of these assets.
That’s because you’re only printing the size of the table and not the nested table sizes. You should be indexing the ContentProvider.RequestQueueSize
to get the amount of assets that are currently in the preload request queue.
for i = 1, #Loadables do
ContentProvider:PreloadAsync(Loadables[i])
Loading.Text = 'Loading (' .. ContentProvider.RequestQueueSize .. ')'
end
Doesn’t work
This doesn’t work since you’re loading one chunk at a time and since PreloadAsync yields, ContentProvider.RequestQueueSize isn’t what you think it will be (probably around 0 till the point you set the text).
From the page on ContentProvider.RequestQueueSize:
Developers are advised not to use RequestQueueSize to create loading bars. This is because the queue size can both increase and decrease over time as new assets are added and downloaded.
The same page also contains an example that can help your problem:
for i = 1, #assets do
local asset = assets[i]
ContentProvider:PreloadAsync({asset}) -- 1 at a time, yields
local progress = i / #assets
bar.Size = UDim2.new(progress, 0, 1, 0)
end
I feel like you’ve already seen this and just went a bit wrong in it’s implementation. Here assets contains all the assets to be loaded, not as chunks but as separate values all at the same level, no nested tables. Here’s how you can implement this in your existing script:
local Loadables = {workspace:GetDescendants(), StarterGui:GetDescendants(), SoundService:GetDescendants()}
-- Make new table which doesn't have nested tables
local assets = {}
for _, container in pairs(Loadables) do
-- container will always be a table with assets in it
for _, asset in pairs(container) do
table.insert(assets, asset)
end
end
for i = 1, #assets do
ContentProvider:PreloadAsync({assets[i]})
Loading.Text = i .. "/" .. #assets
end
I think that ContentProvider is one of the most misunderstood services in terms of developer usage as it relates to creating loading sequences.
PreloadAsync automatically passes the object AND all of it’s descendants into the download queue, so never use GetDescendants with PreloadAsync. It’s a collosally bad idea and you add more unnecessary work to the script (e.g. that table delayering operation). Even worse off is to preload entire service containers. Don’t do this, it nullifies the point of PreloadAsync completely.
PreloadAsync is meant to push assets to the front of the download queue (and in the case of first-use assets, get the client to download them). If you push everything to the front, then there’s virtually no point in using PreloadAsync except as an alternate (and unintended) way of waiting until all specified assets have downloaded without the use of the arbitrary number RequestQueueSize.
Last thing: an engineer advised against using PreloadAsync one asset at a time. Take this information as you will.
cc @NinjoOnline @ankurbohra04
Apparently not
local Loadables = {StarterGui, SoundService}
for _, container in pairs(Loadables) do
for _, v in pairs(container) do
table.insert(Assets, v)
end
end
for i = 1, #Assets do
ContentProvider:PreloadAsync({Assets[i]})
Bar:TweenSize(UDim2.new(i / #Assets, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.025, true)
end
Table expected, got object
That’s because you’re doing pointless iteration over the Loadables container, which the iteration itself isn’t even done properly and is malformed.
local StarterGui = game:GetService("StarterGui")
local SoundService = game:GetService("SoundService")
local Loadables = {StarterGui, SoundService}
for i = 1, #Loadables do
ContentProvider:PreloadAsync({Loadables[i]})
Bar:TweenSize(UDim2.new(i / #Assets, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.025, true)
end
Again though; you really shouldn’t be preloading entire containers nor putting assets in a single-table loading iteration as specified by my above reply. Preload is only meant for downloading assets you need immediately visible on load and the rest can and should be download-streamed in the background.