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
0
Question by Felbinger · Dec 03, 2017 at 08:19 PM · coroutinesienumerator

Change WaitTime, Pause and Resume Coroutines during runtime

I´ve read a couple of topics about coroutines, but haven´t figured out all solutions to my current problems. The situation is that I have a couple of different Coroutines with different WaitForSecond return values. The coroutines should stop when a specific event is happening and resume when the event is over. Furthermore the seconds-value in WaitForSeconds should be changable during runtime.

My current approach is:

     private IEnumerator IncomeCoroutine()
     {
         while (true)
         {
             if (!event)
             {
                 // Only do this if event is not true
                 if (currProduction != 0)
                 {
                     currFood += currProduction;
 
                     if (currFood < 0)
                         currFood = 0;
                 }
             }
 
             yield return new WaitForSeconds(incomeTime);
         }
     }

The problem is that I don´t know how to pause the coroutine without fully stopping it. My workaround is the if-condition in the while-loop so the main part of the IEnumerator won´t be executed during the event. Additionally I´m not sure about the performance, since I have multiple coroutines like this one and also I allocate memory for every "new WaitForSeconds(xSeconds)" in order to be able to change the "xSeconds" during runtime.

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
1
Best Answer

Answer by jdean300 · Dec 03, 2017 at 10:20 PM

Unity's coroutines cannot be paused by default and neither can they be changed once created. It seems like you will need to look into writing custom coroutine IEnumerators. Here is a script for a custom IEnumerator I wrote for a executing an arbitrary action as soon as a coroutine finishes:

     /// <summary>
     /// Routine that executes a given action as 
     /// soon as a given routine finishes
     /// </summary>
     public class DoAfter : IEnumerator
     {
         private readonly IEnumerator m_WaitingFor;
         private readonly Action m_ActionToDo;
 
         public bool MoveNext()
         {
             if (!m_WaitingFor.MoveNext())
             {
                 m_ActionToDo();
                 return false;
             }
 
             return true;
         }
 
         public void Reset()
         {
             
         }
 
         public object Current {
             get { return m_WaitingFor.Current; }
         }
 
         public DoAfter(IEnumerator waitFor, Action doAfter)
         {
             m_WaitingFor = waitFor;
             m_ActionToDo = doAfter;
         }
     }

Regarding the performance impact of WaitForSeconds - you can reuse WaitForSeconds as much as you want without creating new ones. Here is a little setup to do that:

 public static class Wait
 {
     // Cache of wait times
     private static readonly Dictionary<float, WaitForSeconds> m_WaitForSeconds = new Dictionary<float, WaitForSeconds>();

     /// <summary>
     /// Wait's the specified number of seconds.
     /// </summary>
     public static WaitForSeconds ForSeconds(float s)
     {
         // Check cache
         if (m_WaitForSeconds.ContainsKey(s))
             return m_WaitForSeconds[s];

         m_WaitForSeconds[s] = new WaitForSeconds(s);
         return m_WaitForSeconds[s];
     }
 }

Now instead of calling yield return new WaitForSeconds(xSeconds) you'd write yield return Wait.ForSeconds(xSeconds). For any given value of xSeconds there will only be one WaitForSeconds object instantiated. The same value can be used by multiple coroutines at the same time without issue. Note that if xSeconds is randomly calculated or involves a moderate amount of math, float precision limitations will mean the cache of WaitForSeconds values could get really large, so be careful.

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
avatar image
0

Answer by Felbinger · Dec 04, 2017 at 12:51 AM

Thanks, there is pretty much everything I needed in your answer. Especially the Wait class seems very helpful. I solved the pause/play issue by starting and stopping all coroutines in the Update function when specific boolean events are given and immediately toggle them so the start/stop is only called once.

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

71 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

Related Questions

How to use Coroutines in C++/CLI? 1 Answer

Generating Objects at High Speeds 0 Answers

coroutine in update method 1 Answer

Coroutines IEnumerator not working as expected 2 Answers

IEnumerator OnTriggerEnter2D IF statement 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