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 /
  • Help Room /
avatar image
0
Question by GrayRabbitGames · Aug 03, 2016 at 09:28 PM · unity5coroutinesthreadsthreadingfreezing

Why Is This Coroutine Freezing my Unity5 editor?

I feel bad posting this question since it has been posted so many times in so many different ways,

Such as here: http://answers.unity3d.com/questions/838212/why-does-this-coroutine-freeze-my-game.html

And here: http://answers.unity3d.com/questions/586609/waiting-for-input-via-coroutine.html

And here also: https://www.reddit.com/r/Unity3D/comments/3hgg5c/wait_for_input_c/

But I have come to my wits end! Even when I copy the exact code I'm seeing on those pages, my Unity player still freezes as soon as I hit play. What I am trying to do is write a dirt-simple function that waits for a button input from the user, using a coroutine. I've tried several ways of doing this, and they all freeze my game:

     private void SpaceBarToContinue () {
         print ("Press spacebar to continue...");
         StartCoroutine(WaitForButtonPress(KeyCode.Space));
     }

     /*
            //This freezes the game
     private IEnumerator WaitForButtonPress (KeyCode button) {
         do {
             yield return null;
         } while (!Input.GetKeyDown (button));
     }

            //This also freezes the game
     private IEnumerator WaitForButtonPress (KeyCode button) {
         while (true) {
             if(Input.GetKeyDown (button))
                 yield break;
             yield return null;
         }
     }

            //Surprise! This freezes the game
     private IEnumerator WaitForButtonPress (KeyCode button) {
         while (true) {
             if(!Input.GetKeyDown (button))
                 yield return null;
             yield break;
         }
     }

     */

            //Hey maybe this time- nope! This freezes the game
     private IEnumerator WaitForButtonPress (KeyCode button) {
         while (true) {
             if(!Input.GetKeyDown (button))
                 yield break;
         }
         yield return null;
     }

When I run the debug, the program just keeps cycling forever, never giving me the opportunity to end the cycle with button input. I've force-quit about 20 times now trying lots of different variations on the above, and I've finally just decided to ask for help.

Can someone please clue me in to as what simple thing I must be missing here? I would greatly, greatly appreciate any assistance on this matter.

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

Answer by csalzman · Aug 08, 2016 at 02:43 PM

Tried this myself and ran into an issue using "break" to get out of the loop. A more readable way to handle this is to set a bool inside of the coroutine itself and check against that. Here's a C# script that worked on a Unity 5.4 project:

 using UnityEngine;
 using System.Collections;
 
 public class TestingCoroutine : MonoBehaviour {
 
 
     void Start () {
         //Start up and run the SpaceBarToContinue
         SpaceBarToContinue ();
     
     }
         
     private void SpaceBarToContinue () {
         print ("Press spacebar to continue...");
         StartCoroutine(WaitForButtonPress(KeyCode.Space));
     }
 
     private IEnumerator WaitForButtonPress (KeyCode button) {
         //Set your own toggle
         bool waiting = true;
 
         //While loop based on this toggle being true
         while (waiting) {
             //Check for "button" being pressed down. In this case KeyCode.Space
             if(Input.GetKeyDown (button)) {
                 //It was pressed, toggle waiting off so the coroutine will end
                 waiting = false;
                 //Do what you want now
                 Debug.Log("SPACE BAR PRESSED. DO WHAT YOU WANT");
             }
 
             //If the space bar wasn't pressed, wait for the next fixedupdate and check again
             yield return new WaitForFixedUpdate();
         }
     }
 }
 
Comment
Add comment · Show 2 · 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 GrayRabbitGames · Aug 10, 2016 at 09:25 PM 0
Share

Hi czalman, thank you so much for contributing, and even taking the trouble to write out and test code! I think I finally understand what is going wrong.

What I was hoping to do was to create a generic SpaceBarToContinue() function that I could use anytime I ever wanted to have the user press space bar to continue. Whether it was to acknowledge they had read something, or to move to the next step in state machine, or anything. I thought I could accomplish this using a coroutine.

However now I realize that using a coroutine isn't a way to allow your game to "wait" without freezing. Ins$$anonymous$$d, it will tell the game to keep waiting for spacebar, but continue the main program (outside of SpaceBarToContinue() function) anyway.

That means that the only way I can have something specific happen when I press spacebar is to place it within SpaceBarToContinue(), inside the if(Input.Get$$anonymous$$eyDown(button)) check. Furthermore, that means I cannot create a generic SpaceBarToContinue() function the way I had originally envisioned. Ins$$anonymous$$d, I would need to create a separate coroutine function with custom functionality for every time that I want to wait for an input from the user.

I suppose, hypothetically, I could create a WaitForSpaceBar() function which accepts a delegate function as a parameter, and that way could activate any given function using WaitForSpaceBar(DelegateFunction), but that seems like bad design.

I think I will just have to go back to the drawing board and figure out a way to make my game more event-driven, and less sequential, so that I avoid the issue of infinite looping altogether.

If you disagree with anything I'm saying, or you think there is something I am missing, I would gladly listen to any advice you have to offer.

Thank you again for your help!

avatar image csalzman GrayRabbitGames · Aug 11, 2016 at 01:09 AM 0
Share

No problem! $$anonymous$$y first inclination is that a coroutine probably isn't what you're looking for--although I really do like coroutines a lot. I'm wondering if you should consider some sort of global "pause" boolean that most or all of your game objects reference. That way if you need to pause the game you can flip that boolean to true, show what you need to, and wait for the player to hit space bar.

Something like this within Update():

if(pause == true && Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.Space)) { pause = false; //Do other things when you unpause like clear your message for "hit space bar to continue") }

But, that is making a lot of assumptions on what you're going to be using this for :) Good luck! You've got this!

avatar image
2

Answer by flaviusxvii · Aug 03, 2016 at 09:52 PM

It's freezing because you've written an infinite loop that never hands over control back to the main thread. Coroutines run on the MAIN THREAD. So if you keep it locked in a loop nothing else can happen.

try this:

 private IEnumerator WaitForButtonPress (KeyCode button) {
      while (true) {
          if(!Input.GetKeyDown (button)) {
              break;
           }
           // Release the thread until the next game loop.
           yield return new WaitForFixedUpdate();
      }
  }
Comment
Add comment · Show 3 · 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 GrayRabbitGames · Aug 04, 2016 at 02:12 PM 0
Share

Hi Flavius, thank you so much for the assist! That definitely solved the first part of my problem, the program is no longer immediately crashing. However it's not waiting for a button press either; it just breaks out of the while loop immediately and continues the program.

I tried removing the exclamation point (so that it reads "if (Input.Get$$anonymous$$eyDown(button))"), but of course, that just created another infinite loop for me to get stuck in, and the program froze.

I also tried breaking out of the loop if the button was pressed, and yielding otherwise:

        private IEnumerator WaitForButtonPress ($$anonymous$$eyCode button) {
         while (true) {
             if (Input.Get$$anonymous$$eyDown (button))
                 break;
             else
                 yield return new WaitForFixedUpdate ();
         }
     }

But that also just completed the program without waiting for a button press. Again, there must be something here I'm missing.

avatar image flaviusxvii GrayRabbitGames · Aug 05, 2016 at 04:39 AM 0
Share

The 'break' is going to exit the loop which will exit the co-routine. What do you want to happen when a button is pressed. You'd put that where the 'break' currently is if you want to happen over and over. If you want something happen just once, then put it after the 'while' loop.

avatar image GrayRabbitGames flaviusxvii · Aug 08, 2016 at 02:22 PM 1
Share

What I'm looking to have happen is this:

  1. Program is started

  2. function WaitForbuttonPress(spacebar) is called

  3. The program prints "press spacebar to continue"

  4. program waits

  5. program waits

  6. program waits

  7. etc.

  8. The user (me) presses spacebar

  9. The program continues

That's all. But the only two things I've been able to accomplish is either A) an infinite loop that freezes the program, or B) exiting the WaitForButtonPress() function before I press any button.

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Best way to run a long algorithm in the background? 1 Answer

Best option to load large JPG at runtime from a given local folder 0 Answers

Heavy use of Unity API & UI Thread 0 Answers

Loading textures without freezing at runtime 0 Answers

Coroutine Freezing Unity 0 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