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. Dismiss Notice

Coroutine to Detect Sequence of Keys

Discussion in 'Scripting' started by VFran, Sep 23, 2020.

  1. VFran

    VFran

    Joined:
    Sep 6, 2019
    Posts:
    12
    Hi,

    So I'm trying to make a game where there are sequences of arrow keys and players have to press them in a specific order

    (referenced https://forum.unity.com/threads/waiting-for-input-in-a-custom-function.474387/ )

    Code (CSharp):
    1. public class KeyStuff: MonoBehaviour
    2. {
    3.     void Start()
    4.     {
    5.         StartCoroutine(KeySequence());
    6.     }
    7.  
    8.     private IEnumerator KeySequence()
    9.     {    
    10.         yield return waitForKeyPress(KeyCode.Space);
    11.     }
    12.  
    13.     private IEnumerator waitForKeyPress(KeyCode key)
    14.     {
    15.         bool done = false;
    16.         KeyCode[] sequence = { KeyCode.UpArrow, KeyCode.UpArrow, KeyCode.DownArrow, KeyCode.RightArrow };
    17.  
    18.         while (!done)
    19.         {
    20.             if (Input.GetKeyDown(key))
    21.             {
    22.                 done = true;
    23.             }
    24.             yield return null;
    25.         }
    26.            }
    I'm not sure how to detect one key being pressed per call of waitForKeyPress() and advance through the KeyCode array sequence. Any tips?

    Thanks
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,769
    I would do this:

    Put the required Keycodes into an array:

    Code (csharp):
    1. KeyCode[] sequence = new KeyCode[]
    2. {
    3.   KeyCode.S,
    4.   KeyCode.E,
    5.   KeyCode.C,
    6.   KeyCode.R,
    7.   KeyCode.E,
    8.   KeyCode.T,
    9. };
    Then you don't need a coroutine, just an integer that you move along from 0 to sequence.Length.

    If you press the right key, it goes to the next one.

    If you press the wrong key, it goes back to zero.

    If you press ALL the right keys, it fires the special thing off.
     
    SlimeProphet, PraetorBlue and VFran like this.
  3. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,723
    Be careful to actually check all the keys every frame, not just the correct one in the sequence, since you want to penalize the player if they press the wrong button.
     
    VFran and Kurt-Dekker like this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,769
    Good point... easy enough to spin through them all with this:

    Code (csharp):
    1. var AllPossibleKeys = System.Enum.GetValues(typeof(KeyCode));
     
  5. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,723
    Depends on if OP wants literally ANY key to fail, or just some subset, but yeah you basically iterate over some collection of keys and check GetKeyDown for each.
     
    VFran and Kurt-Dekker like this.
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,769
    Oooh another good point... hey OP, run through that list of all KeyCodes and make sure there's not some weird ones in there, like Alt or mouseclick or who knows what... if you check for those keys and they fire, they will break your sequence.

    But when debugging you can always print out the wrong key that did fire, and figure out what might be going down.
     
    VFran likes this.
  7. VFran

    VFran

    Joined:
    Sep 6, 2019
    Posts:
    12
    Got it, thanks for the help!