Search Unity

How Can I Code A Simple, Callable Wait Function that works in 2017.2/3?

Discussion in 'Getting Started' started by Shin_Toasty, Feb 16, 2018.

  1. Shin_Toasty

    Shin_Toasty

    Joined:
    Jun 15, 2017
    Posts:
    48
    I have read about 30 threads on this topic and still can't do this: many of them are old so maybe that's my problem. I have also read the Scripting API and Manual on this.

    My problem is, with IEnumerators I can't CALL this function anywhere I actually need to call it - it just doesn't run I want to be able call it like this

    DoWait();

    within other functions - and for DoWait to just make it pause for x seconds. I don't see why this has to be so complicated with IEnumerators and Coroutines running within an Update etc. etc..

    BTW: I can't use invoke, it causes problems I don't want to get into here.
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well, you can't. I recommend getting over it.

    Wait, unless you're OK with your game locking up, and appearing totally frozen for x seconds. If you're OK with that, then this is totally doable.

    If not, then it's not, and please see previous advice.

    It's because your code is running in the main thread, along with everything else. If you don't return quickly from Update (or FixedUpdate or OnCollisionEnter or whatever other entry point Unity has used to give you a chance to do some very brief processing), then you are blocking the very same thread that draws the scene, the game, catches input, and everything else.
     
    Ryiah and Shin_Toasty like this.
  3. Shin_Toasty

    Shin_Toasty

    Joined:
    Jun 15, 2017
    Posts:
    48
    I am OK with my game locking up, and appearing totally frozen for x seconds.

    Not all games involve rapid movement and explosions.
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Could you describe your use situation specifically?
     
  5. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,192
    Except it won't just be "appearing". It will be literally frozen for x seconds. Will your target audience be happy with that?
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Maybe if you ask : If I knew how to have the delay without the freeze and with it, which would I choose?
    That might be a good question... :)
     
    Shin_Toasty likes this.
  7. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Right, I think your users will object — on Mac, for example, they'll get a spinning beach ball; the CPU temperature will spike, the OS may decide your process has crashed and shoot it in the head.

    Or, depending on what platform you're on, how understanding your users are, and many other things, maybe it'll be fine for your particular use case. Who am I to say? Here's how you might do it:

    Code (csharp):
    1. using System.Diagnostics;  // (needed for Stopwatch class)
    2. ...
    3. public void LockUp(float seconds) {
    4.     var stopwatch = new Stopwatch();
    5.     stopwatch.Start();
    6.     while (stopwatch.elapsed.TotalSeconds < seconds) {
    7.         // lock up this thread good!
    8.     }
    9. }
    And now you can simply call LockUp to simulate a nasty bug as you desire. (Code is off the top of my head and untested, but should be about right.)
     
    Ryiah likes this.
  8. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I don't use any IEnumerators, Coroutines and any of that stuff and frankly neither should you. What you should be aware of though is that means you need to manually do it.

    That means if you want something to wait, for example gameplay, you should code for it:
    Code (csharp):
    1.  
    2.     void Update()
    3.     {
    4.         delayTime -= Time.deltaTime;
    5.         if (delayTime > 0) return;
    6.  
    7.         DoGameStuff();
    8.     }
    9.  
    Primitive code, but gets the idea across. Alternatively, skip executing (I think skip execution is closer to what you need than wait) of an update component with enabled = false; and enabled = true; assuming you have a reference to the component you want to pause and resume Update execution with. I don't use either of the methods I'm describing here but they will work fine for most projects. It's just a matter of style. Try to get in charge of your code, and control it manually - it will help you in the early days quite a bit.

    If you need to make animations "wait" as well, then at the same time you should be setting the animator speed to 0 for that period.

    There's a lot of ways - and the posts above mine are trying to teach you the error of yours. All I can add is "take control".
     
    Shin_Toasty, JoeStrout and Ryiah like this.
  9. Shin_Toasty

    Shin_Toasty

    Joined:
    Jun 15, 2017
    Posts:
    48
    Thanks hippo, that should do it. But there's no error in my way, I don't have one: I got no way! :p I knew IEnumerators weren't right for me here but every 'wait' thread is either about them, or deprecated functions.

    Also: animators .. ? There's an idea - I can call scripts from the animation timeline, so if I made an invisible clip that does nothing but takes 5 seconds (which is all I want to freeze for) to play, at the end I can call a function.

    However, if there's a way my game could freeze iPhone X users and/or shoot them in the head, please let me know.