I am trying to make a loading screen, but it always stops when it tries to load the player and I have waited upwards of 30 seconds and it still consistently doesn’t load the player, which doesn’t seem right. I’ve followed a bunch of tutorials but not of them have or mention this issue.
here is the code:
script.Parent:RemoveDefaultLoadingScreen()
local screen = script.LoadingScreen
local bar = screen.Frame.LoadingBar.LoadedFrame.Loaded
screen.Parent = game.Players.LocalPlayer.PlayerGui
-- getting the things needed to load
local CP = game:GetService("ContentProvider")
local toload = game:GetDescendants()
local TS = game:GetService("TweenService")
-- loading
local total = #toload
for i, v in pairs(toload) do
v = toload[i]
print(v)
TS:Create(bar, TweenInfo.new(0.2,Enum.EasingStyle.Sine,Enum.EasingDirection.In), {Size = UDim2.new(i/total,0,1,0)}):Play()
CP:PreloadAsync({v}) -- it stops here once it gets to the player
if i % 5 then
task.wait()
end
if i == total then
task.wait(1)
end
end
-- done
for i, v in pairs(screen:GetDescendants()) do
if v:IsA("Frame") then
TS:Create(v,TweenInfo.new(1,Enum.EasingStyle.Sine,Enum.EasingDirection.In),{BackgroundTransparency = 1})
elseif v:IsA("ImageLabel") then
TS:Create(v,TweenInfo.new(1,Enum.EasingStyle.Sine,Enum.EasingDirection.In),{ImageTransparency = 1})
end
end
I made it print the “v” value here is what it prints out:
Why you need to load a Player object at the first place? This object is not loadable. It’s created automatically when player joins the game. PreloadAsync is rather used on objects which use any asset or content loaded on-request. Using it on services like Chat, MarketplaceService doesn’t even make sense. These things aren’t loadable.
Use it on Meshes, UI, Decals, Textures, Sounds, Animations, etc…
I load it anyway because I’m not sure how to not load it without not loading everything else. I tried to remove the players from the table by getting the descendants of player service, but the player didn’t load fast enough, and I was worried that it would ruin the accuracy of the loading screen if I just used :WaitForChild(). If there a way to know if the item is loaded or not, I might be able to check if the item is loaded when the script gets to it.
Let me tell it again. Player’s are not loadable assets. They’re not loaded. Only thing what you can load on a player is their model, but not their Player instance. So don’t loaded services, Players or Players descendants, and use it on things which are loadable, as I mentioned before, objects which requires to download an asset from Roblox CDN.
I am trying to make an accurate loading screen, and every tutorial and dev forum post I find loads everything in a table that is created by using game:GetDescendants(), and their loading screens work just fine, so sorry if I seem a little stubborn. The point of the script is not to load everything but to make sure everything is loaded and have a nice Gui to show the progress. If those things are already loaded, I need to have a way to know that with an if statement (and not just listing everything that doesn’t need loading) to move on in the for loop.
If you’d want totally accurate loading screen, you’d be using callbackFunction in function PreloadAsync at the first place, which is fired everytime an asset is processed. Take a look into docs. Code you provided is not accurate loading but a bunch of tweens ran every frame until a loop is done. PreloadAsync is not thread-blocking function, by the “Async” in the name, it means the function is Asynchronous, the loading state of the asset is in the second parameter callbackFunction.
If you want to know the state of object, use the callback, which will mostly return value 2 (None), because you’re trying to load something, what does not require a loading, because it is created.
I assume you want to actually :Play() the tween after creating it, which you aren’t doing in the last lines.
I don’t recommend a custom loading screen, it’s just going to be worse at… loading.
Fixed(?) code anyway:
local ContentProvider = game:GetService("ContentProvider")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local loadingScreen = script:WaitForChild("LoadingScreen")
local bar = screen:WaitForChild("Frame"):WaitForChild("LoadingBar"):WaitForChild("LoadedFrame"):WaitForChild("Loaded")
loadingScreen.Parent = Players.LocalPlayer:WaitForChild("PlayerGui")
ReplicatedFirst:RemoveDefaultLoadingScreen()
-- Loading
local toLoad = game:GetDescendants()
local total = #toLoad
local loaded = 0
local BAR_TWEEN_INFO = TweenInfo.new(0.2, Enum.EasingStyle.Sine, Enum.EasingDirection.In)
ContentProvider:PreloadAsync(toLoad, function(assetId, status) -- Preload Async's second parameter is a callback that is called when the object is loaded.
print(assetId, status)
loaded += 1
TweenService:Create(bar, BAR_TWEEN_INFO, {Size = UDim2.new(loaded/total, 0, 1, 0)}):Play()
end)
task.wait(1) -- Make the player wait.. because why not?
-- done
local TRANSPARENCY_TWEEN_INFO = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.In)
-- Should probably use Canvas Groups here
-- To tween the whole GUI at once
-- https://create.roblox.com/docs/reference/engine/classes/CanvasGroup
for _, object in loadingScreen:GetDescendants() do
if object:IsA("Frame") then
TweenService:Create(object, TRANSPARENCY_TWEEN_INFO,
{BackgroundTransparency = 1}
):Play() -- play tween
elseif object:IsA("ImageLabel") then
TweenService:Create(object, TRANSPARENCY_TWEEN_INFO,
{ImageTransparency = 1}
):Play() -- play tween
end
end
Your method does work but the bar doesn’t change when it loads completely, probably because the callback only happens with the specific assets that need loading (I assume so at least). I think I’m just going to put in a fake bar for now to make it look better, thanks though!