I am working on making a progress bar for the player to see while the game is loading different maps or scenes in my game. Currently, I have a working progress bar that syncs well with the amount of time it takes to load the scene (using Loadlevel Async functions).
However, loading the scene is not what takes the most time. It’s actually what Unity does AFTER the scene is loaded that I need to track the progress of. But I don’t know what Unity is doing after the scene is loaded that takes up so much time? For example, my scene loads in 5 seconds, then there is about 30 - 40 seconds where Unity is initializing my stuff in the scene, before the scene actually activates and appears to the viewer.
So my main question is, what is Unity doing during this time? Is Unity executing the Awake and Start functions of all of my game objects in the scene? Or maybe it is loading textures and meshes into memory?
In regards to a progress bar, perhaps I could somehow set a boolean flag in each game objects Start function that will trigger a percentage progress in my progress bar indicator?
This article may point you in the right direction. 30 - 40 seconds is a very long time to load a scene unless you have a lot of assets that are loaded when the scene is initalized. Are you running some initialization loops in a GameObject’s Awake()/Start() methods?
Actually you just reminded me of something. I do have one main script that uses the “Resources.Load(“xxxxx”)” command in the scripts Awake() function. It’s kind of an overall game manager script.
If I’m doing Resources.Load for about 18 gameobjects in one script, and 6 - 8 in another, could that possibly be the reason for a long initialization time? I should also make mention that my game does have a lot of characters and buildings that are active in the scene when it first starts.
Here is one code statement in the script I mentioned above just for an example (and I’m doing about 18 of these):
I don’t see why loading 18 GameObjects would take that long but there’s only one way to find out:
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
s.Start();
// Resource loading code (or any code you think might be causing the lag)
s.Stop();
Debug.Log("It took " + ((float)s.ElapsedMilliseconds / 1000f) + " seconds to load resources.");
You might also want to check the profiler (Window > Profiler or Ctrl + 7) and see if anything stands out.
Well I timed it with your code and it only took “0.019” seconds to load those resources. So that can’t be it, unfortunately. Thanks for that code though.
But, it’s also not so much about the amount of time for me, but how to measure that amount of time and display it on a progress bar. But I know, in order to do that, I need to know what Unity is actually working on while starting the scene – which what we tested is a part of the process. But even once I know what Unity is executing during this time, I still need to be able to measure it.
What else takes time when starting a scene? It seems like Unity would need to build/enable gameobjects, load resources, execute Awake/Start functions, initialize lighting in the scene, maybe initialize animator components, build terrain perhaps etc… I’m just not sure though.
Since you have Unity Pro, use the Profiler. Even if you don’t get into the depths (just read the manual or watch a video on it) it can tell you what is taking long. If there is any script that has a much higher impact, you found you’re problem, but if everything seems normal, you just have way too many things going on.
Basically, you just start the Profiler, start your scene and just click in the “timeline” to halt execution during your loading. The slowest processes will show up at the top of the list. A small script may finish in 3ms or so, but that very much depends on your machine and whatever you’re doing.
You’re right I actually havn’t worked with the Profiler that much. Although I’ve used it quite a bit for simpler things. It sounds like I need to somehow have the profiler open and running during an actual full game build running, and not just running the game in the editor correct?
Right now, if I use the “record” option on the profiler, I don’t see any data until the game is running, and that doesn’t help at all. Sorry, I’m not new to Unity at all. But I am a bit new in properly using the profiler.
Right, I forgot to mention that you should test this by building your game. Maybe create some empty loader scene with a single button to start your problematic scene, if you don’t have one yet. Then start your build, start the Profiler and attach it to the running process of your built. If I’m not totally wrong, this should give you data while loading, although I have to be honest, that I’ve never had loading times greater than a few milliseconds, so I wouldn’t have noticed, if the Profiler didn’t give me info on those first frames. Just try it with the standalone built. If everything goes wrong, you can still disable all your objects, test, enable on part, test and so on to find the culprit.
I do have an intermediate scene that I launch the problematic scene from with one button, so that won’t be a problem. But, and this is going to sound dumb Xarbrough, how do I simply “Start the Profiler” while the game build is running?
Do I need to have the Unity editor running at the same time? Is there a way to only have the Unity profiler running apart from the editor itself? I see the active profiler has “editor” and then “enter ” options. I’m assuming that’s to somehow link the profiler with someone elses device (as stated in the link you provided).
I apologize if this is annoying, but this is me learning how to profile an active build right now lol. I am trying to google as well, just so you know
You can refer to the section “Attaching to Unity player” on the manual page I linked above for more info, but in short: Run your standalone build game while the Unity editor is open. Then open the Profiler window. There’s a dropdown called “Add Profiler” which will automatically lists all running games in your network, this should only be your standalone build (or maybe it was Active Profiler, I can’t remember right now). Development build must be checked in build settings, too.
It looks like Shaders.Parse is the process that is taking up the most think-time with Unity. Followed slightly by Texture.Load…something, can’t remember exactly now.
I tested loading an empty scene with no objects, just to see if there was some mysterious scene overhead happening, but there doesn’t seem to be. The scene loaded extremely quick.
So, my conclusion is that the the number of gameobjects in the scene at the beginning does affect the time to load (which is kind of a “duh” thing), but just trying to narrow it down.
So, my theory on how to get a progress bar to approximate the load time more closely is to disable ALL of the gameobjects in my big scene, and then through scripting, start enabling them one by one when the scene is loaded. Then as each gameobject gets enabled, show that progress as a percentage on my progress bar.
I’m still not sure if that will work, but I will have to test it. It might not work if Unity automatically starts loading the shaders/textures for disabled gameobjects anyways?
Also remember that my whole goal is to more accurately track the time it will take before the player actually sees the scene come to life. I actually don’t care about loading time (or how long it takes to load the scene), as long as I’m able to more accurately show the player how long it’s going to take before the scene is portrayed to them fully.
Right now the scene actually loads super quick, my progress bar goes to 100% loaded, then there’s an awkward 20 - 30 second gap of time where the scene is initializing while my progress bar inaccurately sits at 100%. Its annoying because I feel I should be able to track the initialization time as well.