Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Creating rope at runtime looks unprofessional because of coroutines. How to fix?
#4
(06-05-2019, 10:55 PM)yyy-2c2p Wrote: Thanks for the reply!
Ahhhhhh interesting, I tried looking into stopping the asynchronous initialization, but couldn't find much about it. I figured it would be easier to just not use a coroutine, because Im not interested in doing something over the course of multiple frames. 

I'm having a hard time getting this to work still though, and having trouble wrapping my mind around the nested coroutines in this issue. I tried a couple different implementations, and physics would never be added, or it would only create some of the ropes and not assign the variables, or some other issue. 

Sorry, but what exactly am I supposed to do here?

Understanding coroutines is pretty essential for working with Unity (or C# for that matter). In your code, since "makinSnakesLoop" is a coroutine itself (which you probably don't need if running the inner coroutine synchronously since you're not yielding anything anymore), you could return the partial results of the inner coroutine:

Code:
IEnumerator coroutine = gg.GetComponent<ObiRope>().GeneratePhysicRepresentationForMesh();
while (coroutine.MoveNext())
         yield return coroutine.Current;

This would yield after each partial result of the initialization coroutine, and would not execute these lines:

Code:
gg.GetComponent<length>().length2 = newController.ss.lengths[x];
     gg.GetComponent<length>().exp = newController.ss.exp[x];
     gg.GetComponent<length>().goal = newController.ss.goals[x];

Until after the inner coroutine had finished.

You could also start the initialization of all snakes at once, then wait until all snakes have been created (asynchronously), then set their length or perform any other post-processing afterwards.
Use something like this to wait for all of them:

Code:
public static IEnumerator WaitForAll(params Coroutine[] coroutines)
   {
       for (int i = 0; i < coroutines.Length; i++)
       {
           yield return coroutines[i];
       }
   }

Then you'd do:

Code:
yield return WaitForAll(coroutine1, coroutine2, coroutine3...);

Which approach to take depends on what exactly you're looking to do, and how it fits with the rest of your game code. Again, the main purpose of coroutines is to spread execution over multiple frames, instead of freezing the whole game until their work is done. If you're creating many snakes and it takes too long, showing a loading bar is the appropriate -most professional- thing to do. All initialization coroutines in Obi return a completion percentage along with a message (both packed in a "ProgressInfo" struct) so that you can get feedback on their current status. You can get it like this:

Code:
while (coroutine.MoveNext()){
         var pctg = coroutine.Current as CoroutineJob.ProgressInfo;
         Debug.Log("Loading..." + pctg.progress*100 + "%");
         yield return pctg;
}
Reply


Messages In This Thread
RE: Creating rope at runtime looks unprofessional because of coroutines. How to fix? - by josemendez - 07-05-2019, 08:56 AM