Unity Community


Results 1 to 17 of 17

  1. Location
    Austin, TX
    Posts
    751

    How can I make a C# Method wait a Number of Seconds?

    How do I make a specific Method (function) in my C# script simply wait a number of seconds?

    I'm not using an Update() function and I'd rather not. In JS there's a method called Yield I think that does it. How does one do it in C#??!?!

    Thanks!
    if (Unity) happiness++;


  2. Location
    Zürich, Switzerland
    Posts
    26,572
    You call the function you want to pause through StartCoroutine and then use yield return new WaitForSeconds(...) or whichever yield you need in it


  3. Location
    Austin, TX
    Posts
    751
    Thanks, Dreamora, I think you've got me going in the right direction, but I need the c# syntax that will work.

    Could you or someone throw me some actual code for that?

    thanks.
    if (Unity) happiness++;


  4. Location
    Austin, TX
    Posts
    751
    It's throwing this error:

    Assets/Scripts/Processor.cs(53,14): error CS1624: The body of `Processor.Process(string)' cannot be an iterator block because `void' is not an iterator interface type

    so do I have to make a separate function??!?

    if (Unity) happiness++;


  5. Posts
    223
    The function needs to return IEnumerator, not void and yes you need another function!

    You should go check out the wiki, it explains this stuff pretty good

    Code:  
    1. public class MyScript : MonoBehaviour
    2. {
    3.     void Start()
    4.     {
    5.         StartCoroutine(MyCoroutine());
    6.     }
    7.  
    8.     IEnumerator MyCoroutine()
    9.     {
    10.         //This is a coroutine
    11.         DoSomething();
    12.        
    13.          yield return 0;    //Wait one frame
    14.    
    15.          DoSomethingElse();
    16.     }
    17. }
    [/code]


  6. Location
    Zürich, Switzerland
    Posts
    26,572
    yes you must make it an extra function.
    you cant yield update (neither can unityscript, it just pretends to but in reality it likely splits the function apart at the yield creating a new coroutine which it calls and immediately yields)


  7. Location
    Austin, TX
    Posts
    751
    Okay, it's a little squirrely...

    I wrote it as a separate function called Wait():

    Code:  
    1.         IEnumerator Wait(float duration)
    2.     {
    3.         //This is a coroutine
    4.        Debug.Log("Start Wait() function. The time is: "+Time.time);
    5.         Debug.Log( "Float duration = "+duration);
    6.          yield return new WaitForSeconds(duration);   //Wait
    7.         Debug.Log("End Wait() function and the time is: "+Time.time);
    8.     }


    which is called from within the Process() function like this:

    Code:  
    1.             Debug.Log("Process() function calling Wait function at "+Time.time);
    2.             Debug.Log("procDuration is "+procDuration);
    3.         StartCoroutine(Wait(procDuration));
    4.             Debug.Log("Process() function after returning from the Wait Function, the time is:"+Time.time);

    The debug log reads this way:

    Process() function calling Wait function at 3.290453
    procDuration is 1.5
    Start Wait() function. The time is: 3.290453
    Float duration = 1.5
    Process() function after returning from the Wait Function, the time is:3.290453


    then the debug log goes on to show a lot of other stuff going on in the Process function and elsewhere, then after 1.5 seconds, it spits this out:

    End Wait() function and the time is: 4.802543

    So what is happening here is that the Wait function immediately returns to the Process function, but stalls at the line "yield return new WaitForSeconds(duration);" before going on.

    Perhaps I can work my code around that, but I was hoping to stall the Process function itself by 'duration' number of seconds.

    Is there any way to do that?

    Thanks for the detailed explanations!
    if (Unity) happiness++;


  8. Location
    Zürich, Switzerland
    Posts
    26,572
    you can not stall the calling function unless its an IEnumerator itself which will not work for update (would be useless anyway as update is called once per frame independent if the previous one finished or not)

    to wait on a coroutine, you would use yield return StartCoroutine(...) if you call it from within a coroutine.


    and reworking the logic is trivial as mentioend. just transfer all after the yield into a new function with return IEnumerator, then move the yield to the beginning of that function and in update where you had the yield, start the coroutine and the nreturn.


  9. Posts
    128
    I think you may need to figure out how the Timer class works in C#.

    Or simply,

    Code:  
    1. public static void MyDelay( int seconds )
    2. {
    3.   TimeSpan ts = DateTime.Now + TimeSpan.FromSeconds( seconds );
    4.  
    5.   do {} while ( DateTime.Now < ts );
    6. }


  10. Location
    Austin, TX
    Posts
    751
    Thanks, Kenny, I'll give that a whirl!

    Dreamora: I don't have an Update function, I'm not sure why you keep talking about Update functions and what I can't do from Update.

    There is no Update.
    if (Unity) happiness++;


  11. Location
    Zürich, Switzerland
    Posts
    26,572
    doh, overread the "not" in your initial posting, thats why.

    though the rest still applies: Function that wants to pause must itself be a coroutine, and transforming a non-coroutine to one you can yield in the middle is basically a matter of adding in place of the yield line
    Code:  
    1.  StartCoroutine(OtherHalf());
    2. }
    3.  
    4. IEnumerator OtherHalf()
    5. {


    I say basically cause there is one thing that will require a few words more and that is if you have local variables in the original functions that are needed in the other half. but you can just specify parameters in OtherHalf and transfer them too. instance and class variables don't need to be sent as they are accessable


  12. Location
    Austin, TX
    Posts
    751
    Kenny,

    using that loop crashes my computer instantly. This is the function:

    Code:  
    1.             endTime = Time.time + procDuration;    
    2.            
    3.             Debug.Log("Process() function calling Wait function at "+Time.time);
    4.             Debug.Log("procDuration is "+procDuration);
    5.             Debug.Log("Time.time = "+Time.time+", endTime = "+endTime);
    6.  
    7. do {} while ( Time.time < endTime );
    8.            
    9.             //StartCoroutine(Wait(procDuration));
    10.             Debug.Log("Process() function after returning from the Wait Function, the time is:"+Time.time);

    It doesn't even print ANYTHING in the debug log at all! It just freezes up! WTF?!

    It was a good idea, but it just ain't happening.

    Maybe the compiler doesn't like the empty do while loop at runtime.
    if (Unity) happiness++;


  13. Location
    Austin, TX
    Posts
    751
    Kk, Dreamora, thanks for the help. I think I can make that work by either making the variables global or passing them from function to function. I can do that!

    I'm going to sleep on it... There may be some other things to consider.

    Thanks you two!
    if (Unity) happiness++;


  14. Posts
    128
    Quote Originally Posted by Vimalakirti
    Thanks, Kenny, I'll give that a whirl!
    Stand corrected,

    Code:  
    1. public static void MyDelay(int seconds)
    2. {
    3.     DateTime dt = DateTime.Now + TimeSpan.FromSeconds(seconds);
    4.  
    5.     do { } while (DateTime.Now < dt);
    6. }


  15. Location
    Austin, TX
    Posts
    751
    Quote Originally Posted by KennyW
    Quote Originally Posted by Vimalakirti
    Thanks, Kenny, I'll give that a whirl!
    Stand corrected,

    Code:  
    1. public static void MyDelay(int seconds)
    2. {
    3.     DateTime dt = DateTime.Now + TimeSpan.FromSeconds(seconds);
    4.  
    5.     do { } while (DateTime.Now < dt);
    6. }
    Kenny, idk why but it just doesn't work properly. That freezes everything up for the duration in seconds. It puts the whole program on pause while it waits. No updates execute, it stops ALL scripts!

    Idk what's up.
    if (Unity) happiness++;


  16. Posts
    128
    Quote Originally Posted by Vimalakirti
    Kenny, idk why but it just doesn't work properly. That freezes everything up for the duration in seconds. It puts the whole program on pause while it waits. No updates execute, it stops ALL scripts!

    Idk what's up.
    perhaps it's because the function is static and is in a single threaded program. You may try to add the codes instead of calling a static method,

    Code:  
    1. DateTime dt = DateTime.Now + TimeSpan.FromSeconds(seconds);
    2.  
    3. do { } while (DateTime.Now < dt);

    If it doesn't, then you may need to work on the Timer class, as the Timer class works on its own CPU thread.


  17. Location
    Gold Coast, Australia
    Posts
    3,593
    Quote Originally Posted by Vimalakirti
    but I was hoping to stall the Process function itself by 'duration' number of seconds.

    Is there any way to do that?
    Why can't you simply use a coroutine?

    What are you doing?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •