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 jfoc2002 · Aug 12, 2020 at 09:23 AM · coroutinewait

IEnumerator hell.

I really don´t know how to solve this.

The problem: I have a "Fader" class. This class handles the screen fading out. In 2-3 or more different cases i need to wait for the fader class to finish up before i can do the next stuff.

All the fader class methods are IEnumerators.

So from my main class i can do this:

     private IEnumerator FadeOut()
     {
         faderCanvas.gameObject.SetActive(true);
         Fader fader = faderCanvas.GetComponent<Fader>();
         yield return fader.StartCoroutine(fader.Fade(1, 0));
     }

But in order to use that, the method calling this has to an IEnumerator:

 public IEnumerator EndDay()
     {
         yield return StartCoroutine(FadeOut());
         //DoNextStuff
     }

Because the "DoNextStuff should not run until the screen is completely black. So i am ending up in every method that needs this Fader class to work to finish must be an IEnumerator.

Isn´t there a better way to solve this?

Comment
Add comment · Show 2
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 Llama_w_2Ls · Aug 12, 2020 at 09:42 AM -1
Share

For your screen to fade in and out, the best solution is to animate a black image that covers your entire screen. You just need two points in each animation clip, one for fully alpha and one for no alpha (making the screen look like it fades in and out). Coroutines are really not the best way to do this. Brackeys has some good tutorials on fade-outs and screen transitions. I suggest you check it out! @jfoc2002

avatar image jfoc2002 Llama_w_2Ls · Aug 12, 2020 at 09:54 AM 0
Share

The fader class solves my needs. The "Animation" way is not the way for me to go on this. Also this doesn´t answer my question.

2 Replies

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

Answer by FlaSh-G · Aug 12, 2020 at 09:51 AM

A coroutine (the IEnumerator method, when used in a StartCoroutine context) allows you to wait for things. A regular method does not allow you to do that, it will be executed in one go and then it's done, not giving Unity the time to redraw the game one or more times. If you need a method to be able to wait until a coroutine is finished, it also needs to be a coroutine.

However, you have two alternatives to coroutines:

  1. async/await - You can do some research on that in the Unity context. I'm personally not too fond of this, because it seems to require a big fat extra framework to work properly, as the default stuff is not documented and thus might have a chance to work 90% of the time and then suddenly stop working - that's due to the "hidden/undefined behavior" nature of async/await.

  2. Callbacks. You can make your coroutine accept a delegate (like System.Action) that the method invokes after finishing the animation. Would look like this:

.

 private IEnumerator DoSomethingAfterSeconds(float seconds, Action onFinish)
 {
     yield return new WaitForSeconds(seconds);
     onFinish();
 }

You can then call it like, for example, this:

 DoSomethingAfterSeconds(5, () => Debug.Log("I waited for 5 seconds!");

To be honest, I don't see the problem with making methods who wait for one another coroutines. And maybe, it's possible to revisit your idea and maybe, you'll notice that you can implement your system(s) without methods waiting for methods waiting for methods to finish.

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 jfoc2002 · Aug 12, 2020 at 10:53 AM 0
Share

Thank you so much! I didn´t know about the amazing callbacks :-) Works like a charm. I don´t even have to use an IEnumerator to call Fader class!

And with the callback it gives my Fader class some really good flexibillity! That was i was after. Thank you!

avatar image
1

Answer by Bunny83 · Aug 12, 2020 at 10:01 AM

Yes, there are workarounds. For example I created the CoroutineHelpers a long time ago. It combines several utilities. First of all it provides a singleton where all coroutines are running on so you don't have any issues when switching between scenes and you can start a coroutine from everywhere. Next it provides a wrapper class (Run class) that wraps around the actual coroutine. This allows you to wait for the same coroutine in different places. To do that the Run class provides a boolean indicating that the coroutine has finished. It also provides the "WaitFor" property to create a new coroutine which can be used inside another coroutine to yield on. Back in the day we did not have the CustomYieldInstruction and this was the only way around this. Maybe I'll update the utility one day -.-


Anyways, in order to have the other class wait for your fader, you would need to give that class / coroutine access to the Run instance you created for the fader.


Depending on your requirements you can also register a delegate that should run when a coroutine has finished by simply using "ExecuteWhenDone" on the Run instance. To start a coroutine with this utility you can simply do

 Run runInstance = Run.Coroutine(YourCoroutine());

This returns a Run instance which you can pass around to other scripts where they can use

 yield return runInstance.WaitFor;

or what would be better now

 yield return new new WaitUntil(()=>runInstance.isDone);


Note that Unity's StartCoroutine method returns a Coroutine instance which generally can be used in another coroutine to wait for this coroutine. However, at least back in the day, it was not possible to have two or more coroutines waiting for the same coroutine instance. That was one of the main reasons I created those utilities. Apart from that it also provides several helpers to run simple delegates. This is useful when you just want to run some code after a certain time or doing something like your fader (with Run.Lerp).


So it's a bit out-of-date but does still work.

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 jfoc2002 · Aug 12, 2020 at 10:55 AM 0
Share

Woaw...really nice. But this is waaaay over my knowledge. But i think this will come handy in the future. Thank you for you answer. I descided to go with callbacks. Works really good for my current needs.

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

142 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

Related Questions

Alternative for semaphores in Unity? 2 Answers

Move a gameobject smoothly without update, without coroutine 2 Answers

Help with waiting for input? I'm too used to how Console.ReadLine() works. 0 Answers

A simple Wait-Function without Coroutine (C#) 12 Answers

Wierd issue with Coroutines? 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