Search Unity

Waiting for a key press in the Update method

Discussion in 'Scripting' started by HaydarLion, Feb 11, 2016.

  1. HaydarLion

    HaydarLion

    Joined:
    Sep 17, 2014
    Posts:
    62
    Hi,
    I'm working on a game in which I want the game to wait in the update function inside an if statement until the player presses a specific key. Is there any specific way I can do that?
    Thanks.
     
  2. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,539
    nope, blocking the Update method will block the game.

    You should be testing on a per frame basis and reacting.

    If you have a long routine that must stop mid way and wait for a duration until some event occurs in game, that's what 'Coroutines' are for. You can start up a Coroutine, resolve some code, then in an while/foreach loop keep yield returning null until some event occurs.

    Like so:
    Code (csharp):
    1.  
    2. IEnumerator SomeRoutine()
    3. {
    4.  
    5.     //do stuff
    6.  
    7.     //wait for space to be pressed
    8.     while(!Input.GetKeyDown(KeyCode.Space))
    9.     {
    10.         yield return null;
    11.     }
    12.  
    13.     //do stuff once space is pressed
    14.  
    15. }
    16.  
    This though is more for setting up sequences of actions over a duration of time. Rather than reacting to user input repeatedly.

    If you're doing something where you want to jump on spacebar pressed, a routine is not how you'd go about it. Update is. And the update code would just check each frame if the key was pressed.

    'Update' is like a while loop, its code operating repeatedly, once per frame.

    Code (csharp):
    1.  
    2. void Update()
    3. {
    4.     if(Input.GetKeyDown(KeyCode.Space))
    5.     {
    6.         //do jump
    7.     }
    8. }
    9.  
     
    Issylin and Magiichan like this.
  4. HaydarLion

    HaydarLion

    Joined:
    Sep 17, 2014
    Posts:
    62
    Ok. What do you recommend I do for a turn-based rpg battle system where I want the game to wait for you to press a button (to finish reading the text) before ending your turn.
     
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,539
    That'd be a coroutine.

    You'd start a coroutine, the coroutine would display the message, then it'd wait for a keypress. Just like in my coroutine example above.
     
  6. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    In this case, you need to setup a manager to handle turns. Then give 'turn' access to the next player where they can input w/e you need.
     
  7. joegatling

    joegatling

    Joined:
    Jul 16, 2013
    Posts:
    7
    A simple way to set this up would be to have a GameObject that handles whose turn it is, and have other objects refer to that. For example:

    Create a GameObject with a script called GameManager.cs with the following:
    Code (CSharp):
    1. public class GameManager : MonoBehaviour
    2. {
    3.     public int currentPlayer = 0;
    4.     public int totalPlayers = 2;
    5.  
    6.     public void NextPlayer()
    7.     {
    8.         // Update the current player, use the modulo operator to wrap around
    9.         currentPlayer = (currentPlayer + 1) % totalPlayers;
    10.     }
    11. }
    Then your individual game pieces could check to see if they need to act:
    Code (CSharp):
    1. public class GamePiece : MonoBehaviour
    2. {
    3.     public int myPlayerNumber = 0;
    4.     public GameManager gameManager;
    5.  
    6.    void Update()
    7.     {
    8.         if(gameManager.currentPlayer == myPlayerNumber)
    9.         {
    10.             // It is my turn, do my logic
    11.  
    12.             if(Input.GetKeyDown(KeyCode.Space))
    13.             {
    14.                 gameManager.GoToNextPlayer();
    15.             }
    16.         }
    17.     }
    18. }
     
  8. THEREALIZATION

    THEREALIZATION

    Joined:
    Mar 9, 2017
    Posts:
    2
    I think better solution for coroutine is like:
    Code (CSharp):
    1. IEnumerator SomeRoutine()
    2. {
    3.  
    4.     //do stuff
    5.  
    6.     //wait for space to be pressed
    7.     yield return new WaitUntil(() => Input.GetKeyDown(KeyCode.Space));
    8.  
    9.     //do stuff when space is pressed
    10.  
    11. }
    This is another solution without while loop.. You can see also lambdas article right here: https://docs.microsoft.com/en-us/do...ents-expressions-operators/lambda-expressions