Waiting for a key press in the Update method

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.

Input.GetKeyDown

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:

IEnumerator SomeRoutine()
{

    //do stuff

    //wait for space to be pressed
    while(!Input.GetKeyDown(KeyCode.Space))
    {
        yield return null;
    }

    //do stuff once space is pressed

}

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.

void Update()
{
    if(Input.GetKeyDown(KeyCode.Space))
    {
        //do jump
    }
}
2 Likes

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.

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.

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.

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:

public class GameManager : MonoBehaviour
{
    public int currentPlayer = 0;
    public int totalPlayers = 2;
  
    public void NextPlayer()
    {
        // Update the current player, use the modulo operator to wrap around
        currentPlayer = (currentPlayer + 1) % totalPlayers;
    }
}

Then your individual game pieces could check to see if they need to act:

public class GamePiece : MonoBehaviour
{
    public int myPlayerNumber = 0;
    public GameManager gameManager;
  
   void Update()
    {
        if(gameManager.currentPlayer == myPlayerNumber)
        {
            // It is my turn, do my logic

            if(Input.GetKeyDown(KeyCode.Space))
            {
                gameManager.GoToNextPlayer();
            }
        }
    }
}

I think better solution for coroutine is like:

IEnumerator SomeRoutine()
{

    //do stuff

    //wait for space to be pressed
    yield return new WaitUntil(() => Input.GetKeyDown(KeyCode.Space));

    //do stuff when space is pressed

}

This is another solution without while loop… You can see also lambdas article right here: Lambda expressions - Lambda expressions and anonymous functions - C# reference | Microsoft Learn