Creating a Loading Bar based off of number of assets loaded

I’m using PreloadAsync to load assets in a GUI upon the LocalPlayer’s entry.

I’d like to create a Loading Bar (literally just a frame) that loads in equal increments depending on the number of assets there are to load (Lets say 30). How would I go about doing this?

20 Likes
bar.Size = UDim2.new(numloaded/numall, 0, 1, 0)

Put a frame inside your frame that’s sized with scale and use this on that frame

2 Likes

As far as I know, If you wanted to have an exactly accurate progress bar, you’d have to call PreloadAsync 1 by 1 through your array, as such:

local loadables = {} -- your loadable array.

local amount_loaded = 0
	
for i = 1, #loadables do
	ContentProvider:PreloadAsync({loadables[i]})
	amount_loaded = i
	loading_text.Text = i.."/"..#loadables
	bar.Size = UDim2.new(amount_loaded/#loadables,0,1,0)
end

64 Likes
local loadables = {} -- your loadable array.

local thread = coroutine.running()
local amount_loaded = 0
	
for i = 1, #loadables do
    coroutine.wrap(function()
        ContentProvider:PreloadAsync({loadables[i]})
        amount_loaded = amount_loaded + 1
        coroutine.resume(thread)
    end)()
end

while amount_loaded ~= #loadables do
    coroutine.yield()
    loading_text.Text = amount_loaded .."/"..#loadables
    bar.Size = UDim2.new(amount_loaded/#loadables,0,1,0)
end
9 Likes

I’ve quit games that tried force me to stare at their fancy loading bar. The best loading bar is no loading bar. Working around it will be different for every game, but if you have a waiting room for the next round, a consistent starting area, or a starting customization gui, you know which assets need to be loaded first. Just load those, then let Roblox do its thing and stream in the rest in the background.

2 Likes

Subjective. Some games simply do not look swell with missing assets, or possibly can’t run without such assets. There’s a reason that most or all games use loading screens or bars and don’t run the game assuming that they can be loaded in later; having such on Roblox games is no different.

The one thing I can agree with here is that every game has a way to workaround starting people off with a loading bar though. It’s good to preload assets that need to be seen immediately first before anything else, that way when people are preoccupied with things they can see, what they can’t see is streamed in the background.

14 Likes

I’ve also removed the default loading screen so I mean, it doesn’t make that much of a difference. I’ve tested it and it’s as quick if not quicker than the loading screen Roblox has.

IMO It’s better to sacrifice some of the aesthetic of a game by allowing players to load in assets as they play rather than risk giving a bad first impression with a long loading screen

2 Likes

Now, if your game has lots of assets, inserting them into it will be a pain

Ehhh,

Also, your code isn’t very flexible for other users to use. You must take that into consideration and also provide neat and properly presentable code (with indents and formatted :persevere:). (Talking about that workspace.HangoutFloor1:GetDescendants())
Instead of use elseif’s, you could have just used a basic if statement with or.

And I don’t mean to be rude randomly judging code, just looking to fix other’s code and improve scripting community.

1 Like

PreloadAsync automatically takes in the related asset ids of descendant instances, so there’s no need for a developer to manually push an instance’s descendants into a table for PreloadAsync. Additionally, the table which PreloadAsync operates on only takes instances, not strings.

It’s not recommended that you do this anyhow because this isn’t proper use of PreloadAsync but for developers that insist on doing it, then there’s a different way to get this done which is… just using the array that GetDescendants returns, lol. It wouldn’t preload the ancestor instance though and inserting it would be redundant because then the ancestor’s descendants would be preloaded twice.

local assetCache = workspace.HangoutFloor1:GetDescendants()

Loadables in Fiery’s code sample is just a placeholder to represent the assets that you’re passing into PreloadAsync. Realistically you should never be passing a large amount of assets to PreloadAsync because that’s the same as passing nothing and you’re thus not getting the full benefits of PreloadAsync other than a long loading screen which is bad for UX. Only assets the player should be seeing immediately (e.g. main menu content) should be through PreloadAsync.

5 Likes

Anyone know if there’s a way to do this but instead of having loading_text.Text = amount_loaded .."/"..#loadables you have it tell you which assets are being loaded?

loading_text.Text = 'Loading ' .. loadables[i].Name

where loadables[i] is the object currently being loaded and we’re taking it’s Name property.

1 Like

Something I wrote for my game

local count = 0
for i = 1, #assets do
	count = i
	script.Parent.tell.Text = i.."/"..#assets
	bar.Size = UDim2.new(count/#assets,0,bar.Size.Y.Scale,0)
	game.ContentProvider:PreloadAsync({assets[i]})
end

Assets is a table with all the things I want to load, it goes through each table item and loads it, the PreloadAsync yeilds until the thing is loaded

I forgot the reason why I even made the count variable but this never failed to work so uhhhh

Realistically you should never be passing a large amount of assets to PreloadAsync because that’s the same as passing nothing and you’re thus not getting the full benefits of PreloadAsync other than a long loading screen which is bad for UX.

Very True. Just Bumped into that Issue trying to Load a Map with Around 5K Assets. Taking 2 Game Rounds to Finish. Guess Ill let Roblox Handle that And Use the Loading for UI and Instant Sight type of Stuff!