background
typically, the main scene of the game contains more resources, which can cause the scene to load for a longer period of time. To avoid this problem, you can load the loading scene first, and then load the main scene with the loading scene. Because the loading scene contains fewer resources, it loads faster. When loading the main scene, a progress bar is typically displayed in the loading interface to inform the player of the current loading progress. In Unity Application.LoadLevelAsync
, the game scene can be loaded asynchronously by invoking a function, and AsyncOperation.progress
the value of the query is used to get the progress of the scene loading.
Try--encounter a problem
First step after loading the loading scene, call the following LoadGame
function to start loading the game scene, load scene 1 with asynchronous loading (loading scene is 0, home view is 1), through unity provides the Coroutine mechanism, We can conveniently call the function at the end of each frame SetLoadingPercentage
to update the value of the progress bar displayed in the Interface.
PublicvoidLoadgame(){Startcoroutine(Startloading_1(1));}PrivateIEnumeratorStartloading_1(int scene) {asyncoperation op = application. Loadlevelasync (scenewhile (!. Isdone) {setloadingpercentage ( Op. Progress * 100); yield return new waitforendofframe (); } } /span>
The effect of the final progress bar is shown below:
Progress bar does not show the progress of the load, but a pause to switch a number, and then pause to switch a number, and finally no display 100% in the case of the switch to the main scene. The reason is Application.LoadLevelAsync
not the real background load, it loads some game resources at each frame, and gives a progress value, so when loading will still cause the game lag, AsyncOperation.progress
the value is not Accurate. Unity automatically switches the scene when the main scene is loaded , so the code in the while loop inside the code is not called, causing the progress bar to not show 100%.
patch--100% Complete
In order for the progress bar to display 100%, The trickery point is to AsyncOperation.progress
multiply the value by 2, so that when loaded to 50%, the interface will display 100%. The downside is that when 100% is displayed on the interface, the user will have to wait a while before entering the Game. In fact, Unity provides a way to manually switch scenes, AsyncOperation.allowSceneActivation
set to false
prevent unity to automatically switch scenes after loading, the modified code is StartLoading_2
as Follows:
This function isn't workPrivateIEnumeratorStartloading_2(int scene){AsyncOperationOp=Application.Loadlevelasync(scene); op. Allowsceneactivation = falsewhile (!. Isdone) {setloadingpercentage ( Op. Progress * 100); yield return new waitforendofframe (); } op. Allowsceneactivation = true /span>
We will first set to AsyncOperation.allowSceneActivation
false
, when loading is complete, then set to true
. The code does not look wrong, but the result is that the progress bar will end up staying at 90% and the scene will not Switch. By printing log Discovery AsyncOperation.isDone
all the false
AsyncOperation.progress
time, the value increases to 0.9 and remains the same, meaning that the scene will never be Loaded.
In this post to find the answer, the original allowSceneActivation
set as false
after, unity will only load the scene to 90%, the remaining 10% to wait until allowSceneActivation
set to true
load , which has to be said to be a pit. So the code changes to the Following. When you AsyncOperation.progress
reach 0.9, update the progress bar directly to 100% and set it to AsyncOperation.allowSceneActivation
ture
allow unity to continue loading the unfinished scene.
PrivateIEnumeratorStartloading_3(int scene){AsyncOperationOp=Application.Loadlevelasync(scene);Op.Allowsceneactivation=False;While(Op.Progress< 0.9f) {setloadingpercentage (op. Progress * 100); yield return new waitforendofframe (); } setloadingpercentage (100yield return new waitforendofframe (); op. Allowsceneactivation = true /span>
The final results are as follows:
polishing--adding Animations
Although the above progress bar solves the problem of the 100% display, it does not look natural and beautiful because the progress Bar's value update is not continuous. To look like a continuous load, you can insert a transition value every time the progress bar is Updated. Here I adopt the strategy is that when the value is obtained AsyncOperation.progress
, not immediately update the progress bar of the value, but each frame in the original value plus 1, so that will produce the digital scrolling animation effect, Thunder shows the download progress is used this method.
PrivateIEnumeratorStartloading_4(int scene){IntDisplayprogress=0;IntToprogress=0;AsyncOperationOp=Application.Loadlevelasync(scene);Op.Allowsceneactivation=False;While(Op.Progress<0.9f){Toprogress=(Int)Op.Progress*100;While(Displayprogress<Toprogress){++Displayprogress;Setloadingpercentage(Displayprogress);YieldReturnNewwaitforendofframe (); } } toprogress = 100 while (displayprogress < Toprogress) {++displayprogresssetloadingpercentage (displayprogressyield return new waitforendofframe (); } op. Allowsceneactivation = true;}
displayProgress
To record the values to be displayed on the progress bar, the last progress bar is animated as Follows:
Compare the first type of progress bar
Summary
If you need to parse data tables, generate object pools, and network connections before loading the main game scene, you can assign a weight to these operations and use these weights to calculate the progress of the LOAD. If your scene loads very fast, you can use a fake progress bar that lets the player look at the loading animation for a few seconds before loading the SCENE. In short, Although the progress bar is small, but it is not easy to do Well.
Https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadSceneAsync.html
Https://docs.unity3d.com/ScriptReference/AsyncOperation.html
AsyncOperation Description
Asynchronous Operation Coroutine.
You can yield until asynchronous operation continues, or manually check whether it's done (isDone) or Progress (progress).
See Also:SceneManager.LoadSceneAsync, Assetbundle.loadasync.
Variables
Allowsceneactivation |
Allow scenes to being activated as soon as it is ready. |
IsDone |
Has the Operation finished? (Read only) |
Priority |
Priority lets your tweak in which order async operation calls would be Performed. |
Progress |
What ' s the operation ' s PROGRESS. (Read only) |
"go" Unity3d issues encountered in making loading scene progress bar Loadlevelasync,asyncoperation