Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

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,380
    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,380
    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