Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
1
Question by Em3rgency · Aug 25, 2018 at 07:00 AM · c#coroutinefreezecoroutineswhile loop

Can't get while loop to execute more than once in a coroutine before yielding [Solved]

This has been driving me crazy. If anyone has insight in why it's behaving like this, I'd love to hear it.

So, I have a while loop inside a coroutine. It works fine. However, yielding each frame is too slow for my purposes. So I'm trying to make it yield after every 4 loops. In my test case I want the while to execute a total of 1000 times (yielding 250 times along the way). It always freezes unity after around 400 total loops. Help?

 private void CoroutineFunction() 
 {
     int loop = 0;
     //start = 0; end = 1000;
     while (start != end)
     {
         start++;
         //some instantiation code omited here
         if (loop % 4 == 0)
         {
             yield return null;
         }
         loop++;
     }
 }

To be clear - if I remove the loop variable and the if % check, and just yield every frame it works. But why would my changes make unity freeze? How would they cause the while loop to get stuck? How else could I implement yielding every x loops?

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

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Aug 25, 2018 at 11:28 AM

It might depend on your "some instantiation code omited here". The code provided should work fine. Maybe each instantiated object also starts this or a similar coroutine? Since there's no yield between the start and you instantiate code it runs synchronously. Though if you have an infinite recursion you should get a stack overflow and not a freeze (though if the instantiate code is quite heavy it might take a while).


If you just want a certain call count per second you could use a custom fixed update callback. This works similar to Unity's FixedUpdate but you can specify any desired call rate, even 10000 times per sec. Though it does not perform load balancing. So you should ensure the cost of a single call is not higher than the deltatime between two fixed calls. So when doing 10000 calls each call should not take longer than 0.0001 seconds (0.1ms). Keep in mind that at a visual framerate of 60 fps there would be about 166 calls each frame.

The CustomFixedUpdate does have a "MaxAllowedTimeStep" (like Unity has) to not get caught in a death spiral.

Comment
Add comment · Show 4 · 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 Em3rgency · Aug 25, 2018 at 04:19 PM 0
Share

Thanks for trying to help me figure this out!

I'm happy to hear you too think that the code should work as is.

This is the only coroutine I have and there is no recursion.

The missing part of the code calls FindObjectsOfType(); for two types of objects, foreach-es through them and calls a function for each of them. The function looks at some other parameters of the object and decides if it should Destroy() itself or Instantiate() more copies of the object. That's about it. As the while loop in the coroutine continues, there tends to be more and more objects found by the Find call, but it's nothing unity can't handle. The Update() method for each of those objects immediately "returns" if they detect the coroutine is running. So there is no recursion.

It's not that I want a certain call count per second. This code runs perfectly well synchronously, but it freezes for the few seconds while it does the calculations. That is why I offloaded it onto a coroutine. And as I said, if I yield every while loop, it crunches all the data fine, no problems.

Any other ideas what I should check or try?

avatar image Bunny83 Em3rgency · Aug 25, 2018 at 04:41 PM 0
Share

Well as i said i don't see any reason why this loop should freeze. If "start" is actually incremented reliably by 1 each time you could get rid of your loop variable all together and just do

 if (start % 5 == 0)
 {
     yield return null;
 }

This should yield once every 5 iterations.

A bit unrelated but the way you setup your loop variable results in some inconsistent behaviour. You set "loop" to 1. So it does 4 iterations and then enter your if statement. However since you increment loop at the end you effectively setting loop to "2". So from now on you only yield every third iteration. Resetting loop is not really necessary when you use modulo. If you reset the variable each time it would be much more readable to just use

 loop++;
 if (loop > 4)
 {
     loop = 0;
     yield return null;
 }

avatar image Em3rgency Bunny83 · Aug 25, 2018 at 04:58 PM 0
Share

Good point on the reset. It's because I've gone through many iterations of trying different things, so that's a bit of a jumble. You're perfectly correct on the the modulo thing. It's not the problem though.

However, I found a lead on what might be the cause though! It seems if you call Destroy() on an object, it only gets destroyed on the next Update loop, but before rendering (so its still the same frame). But now, I do 4 (or well.. 3) loops, before yielding. If the first loop ends up calling Destroy(), then the other 3(2) loops will also call Destroy() on the same object. I'm not sure how Unity works that far under the hood, but I think this might cause a problem.

Looking into a way to check if Destroy() has been called on an object yet. Worst case scenario, I can use an internal variable. I'll update you if anything comes of this.

Show more comments
avatar image
0

Answer by Em3rgency · Aug 26, 2018 at 03:50 PM

So the issue was related to the omitted Instantiation code. In hindsight the problem is obvious.

The objects I was instantiating were running some internal code as part of the coroutine that instantiated them. And several of them had while() loops of their own, that in my situation had become infinite loops. The reason was that they did not get properly initialized as their Start() functions were not called until next frame (by which time it was already too late).

The solution was simply to use Awake() instead of Start() on all objects instantiated on the coroutine. This ensures they are properly initialized, even if the next frame hasn't started yet.

Comment
Add comment · 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

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

540 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 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 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 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

Can I run multiple instances of the same coroutine in parallel? 1 Answer

How to wait for a co routine to finish when calling from a method 1 Answer

Loop Coroutine For A Demo Mode 1 Answer

Coroutine Won't Stop Using IEnumerator 1 Answer

move inside a coroutine 2 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