Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by DkSker · Oct 29, 2021 at 01:34 PM · coroutineloading screenmap-generation

Loading screen bar not loading.

Problem: I am making a loading screen for my rts game. I have a simple Main menu with a button on it, and when clicked, it will load a scene using LoadSceneAsync and then it will start 2 coroutines, the first one is for the scene loading progress, and the second one is for my world generation loading bar:

    float totalSceneProgress = 0;
    float[] totalObjectProgress = { 0, 0, 0 };
     IEnumerator GetSceneLoadProgress()
     {
         for (int i = 0; i < scenesLoading.Count; i++)
         {
             while (!scenesLoading[i].isDone)
             {
                 totalSceneProgress = 0;
 
                 foreach (AsyncOperation op in scenesLoading)
                 {
                     totalSceneProgress += op.progress;
                 }
 
                 totalSceneProgress = Mathf.Clamp01((totalSceneProgress / scenesLoading.Count) / 0.9f);
                 yield return null;
             }
         }
     }
 
     IEnumerator GetTotalProgress()
     {
         float totalProgress = 0;
         
         while (!MapGrid.doneLoading)
         {
             for (int i = 0; i < totalObjectProgress.Length; i++)
             {
                 switch (i)
                 {
                     case 0:
                         totalObjectProgress[i] = MapGrid.mapLoading / mapLoadingMax;
                         print(MapGrid.mapLoading + " / " + mapLoadingMax);
                         break;
                     case 1:
                         totalObjectProgress[i] = MapGrid.terrainLoading / mapLoadingMax;
                         break;
                     case 2:
                         totalObjectProgress[i] = MapGrid.resourceLoading / mapLoadingMax;
                         break;
                 }
             }
             totalProgress = (totalObjectProgress[0] + totalObjectProgress[1] + totalObjectProgress[2] + totalSceneProgress) / (totalObjectProgress.Length + 1);
 
             slider.value = totalProgress;
 
             yield return null;
         }
 
         print(totalObjectProgress[0]);
 
         yield return new WaitForSeconds(0.5f);
         loadingPage.SetActive(false);
     }

I noticed a problem though, when I generate my map, I use for loop in a function. For example, my code will loop 40,000 times for map width and height of 200 and 200. Each loop, I have set a variable to be added one everytime it looped once. In my coroutine, I am trying to access these numbers and getting a percentage out of them. I thought if I did that, the bar will go up, however it only stopped at 25 percent (Meaning it only accounted the scene loading progress) and the rest of the 75 (Which I set to be the map generation progress) won't show and the game will just load when its done without making the bar go up.

I have tested this and found that in my coroutine, the numbers in totalObjectProgress will always stay at 0 despite my other script updating the numbers.

I tried to debug this by making my script print out the index each time it adds 1 to the progress variable, as I suspected, instead of working like an update method, it lags, and then suddenly my console is filled with 40,000 print messages all at once.

Is there a way to make my map generation not freeze the game and will go up one by one or at least slow enough so it does not try to load in all at once and freeze the game.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by bdubbert · Oct 29, 2021 at 07:54 PM

Coroutines in Unity are not true coroutines: they still run on the main Unity thread and are updated every update cycle. That means if a process hangs the main Unity thread (for example, a large FOR loop) then the execution of the coroutines will hang as well.


You have a few options here -


  1. Break up your for loop across several update cycles by only doing parts of the for loop each update, or put it in a unity coroutine and split up chunks of the calculation with a yield return

  2. Use an actual multithreaded approach. C# makes it pretty easy to create and launch threads. Make sure that you are putting your for loop on a separate thread though - if you put your progress bar on a different thread the progress bar script will run correctly but the UI itself will never update to reflect it until the main thread becomes unstuck again.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DkSker · Oct 30, 2021 at 12:39 PM 0
Share

Thank you for your response, I have placed my for loops of the initialization of my map into a coroutine, and yield return null each 200 loops, and also I will now update the loading bar using the Unity update method.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

139 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do you change UI text in the middle of a method? 1 Answer

Loading screen with LoadLevelAsync 0 Answers

How to load scene when async.progress is 0.9? 0 Answers

Loading screen works perfectly with one scene only and not with others 0 Answers

Loading Screens are confusing 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges