Loading bar not fully completing

I was making a loading screen, however, I noticed that when it finished loading, the loading bar’s size won’t change. The other things, like the text changing, do change, but the bar (frame.Frame.Frame) doesn’t change. It changes when assets are loading; however, it does not change at all when the loading is done or when you skip the loading

Script:

game:GetService("ReplicatedFirst"):RemoveDefaultLoadingScreen()
local contentProvider = game:GetService("ContentProvider")
local frame = script.Parent
local percent = frame.percent
local exact = frame.exact

local tipIndex = 1

local tips = {
	"put your money in your atm in order to avoid losing some upon death",
	"atms give you 10% interest every 10 minutes you have money in there!",
	"honey buns are great! don't put them in the microwave though...",
	"get a fresh cut at cut's and clippers!",
	"this loading screen sure does take a while...",
	"make sure not to do anything <strong><u>too</u></strong> illegal",
	"you can check all your past unnessecary transactions at the bank",
	"fun fact: this tip was made on april 17th, 2025"
}

local loadBlur = Instance.new("BlurEffect")
local loading = true
local skippedLoading = false
loadBlur.Parent = game:GetService("Lighting")
loadBlur.Size = 60

game:GetService("StarterGui"):SetCoreGuiEnabled(Enum.CoreGuiType.All, false)

local allAssets = workspace:GetChildren()
local skippedAssets = {}
local totalAssets = #allAssets

frame.skipbtn.Frame.TextButton.MouseButton1Click:Connect(function()
	skippedLoading = true
end)

-- Helper function to preload with timeout
local function preloadWithTimeout(asset, timeout)
	local loaded = false
	local thread = coroutine.create(function()
		contentProvider:PreloadAsync({asset})
		loaded = true
	end)
	table.insert(skippedAssets, asset)
	coroutine.resume(thread)
	local startTime = tick()
	while not loaded and tick() - startTime < timeout do
		task.wait(0.1)
	end
	return loaded
end
local function tipFunction()
	while loading do
		local tipLabel = frame.tips
		tipLabel.Text = tips[tipIndex]
		tipIndex = tipIndex % #tips + 1
		task.wait(5)
	end
end
task.spawn(tipFunction)
for i, asset in ipairs(allAssets) do
	loading = true
	frame.currentasset.Text = "Currently loading: " .. asset.Name
	if skippedLoading then
		break
	end
	-- Preload with 15 second timeout
	local loaded = preloadWithTimeout(asset, 5)
	if not loaded then
		warn("Skipped asset (timeout): " .. asset:GetFullName())
	end
	percent.Text = math.round(i / totalAssets * 100) .. "%"
	frame.Frame.Frame:TweenSize(UDim2.fromScale(i / totalAssets, 1), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, .1)
	exact.Text = i .. " out of " .. totalAssets .. " assets loaded."
end

loading = false

if not skippedLoading then
	frame.Frame.Frame.Size = UDim2.fromScale(1,1)
	percent.Text = "100%"
	exact.Text = "Game loaded. Spawning in soon."
	task.wait(3)
	repeat task.wait()
		frame.GroupTransparency += 0.01
		loadBlur.Size -= 1
	until frame.GroupTransparency >= 1
	game:GetService("StarterGui"):SetCoreGuiEnabled(Enum.CoreGuiType.All, true)
	task.wait()
	frame.Parent:Destroy()
else
	frame.Frame.Frame:TweenSize(UDim2.fromScale(1,1), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, .5)
	percent.Text = "100%"
	exact.Text = "Loading skipped. Spawning in soon."
	task.wait(3)
	repeat task.wait()
		frame.GroupTransparency += 0.01
		loadBlur.Size -= 1
	until frame.GroupTransparency >= 1
	game:GetService("StarterGui"):SetCoreGuiEnabled(Enum.CoreGuiType.All, true)
	task.wait()
	frame.Parent:Destroy()
end

i think the reason this is happening is because you try setting the Size property while a TweenService tween is active, which makes it basically do nothing; you can only set the property after the tween is done.

i would make it so that it waits until all the assets have been preloaded then the bottom code can run, that would achieve your desired result.

omgosh, why don’t you just:

local tween_service = game:GetService "TweenService"
local content_provider = game:GetService "ContentProvider"

local assets = {}--add your assets here
local loaded_assets = 0 --keep track of loaded assets
local loading_bar = --your loading bar

--because of preloadasync yielding, you can enable your blur before preloadasync, and disable it after.
--loadBlur.Parent = game.Lighting
--loadBlur.Size = 60
content_provider:PreloadAsync(assets, function(assetId: string, assetFetchStatus: Enum.AssetFetchStatus)
      loaded_assets += 1--increment loaded asset
      tween_service
             :Create(loading_bar, TweenInfo.new(.1), {Size = Udim2.fromScale(loaded_assets/#assets, 1)})
             :Play()

    --you can add your frame.currentasset.Text = string.format("Currently Loading: %s", assets[loaded_assets + 1].Name) here
--you can also update your percentage here:
  --exact.Text = string.format("%d out of %d assets loaded", loaded_assets, #assets)
 --percent.Text = math.round(loaded_assets / #assets * 100).."%"
--you might even want to modify the tip here!
--tipLabel.Text = tips[math.random(1, #tips)]
end)--provide a callback that runs whenever a single asset in the given assets array is loaded

--do stuff after your loading is done!
--TweenService:Create(loadBlur, TweenInfo.new(3), {Size = 0}):Play()
--TweenService:Create(frame, TweenInfo.new(3), {GroupTransparency = 0}):Play()
--frame.Parent:Destroy()?
--etc...

your code seems incredibly unoptimized. Do not use TweenSize, use TweenService; TweenSize is deprecated.

Why are you using workspace as the storage for your assets??? Contentprovider only loads materials, textures, images, meshes, sounds and animations, it doesn’t load parts. Instead, shove all of your assets into a single folder in replicated storage and use that instead for :GetChildren.

Hope this helps?

1 Like