How to await player input using Coroutines

by reincarnationofstackexchange   Last Updated July 26, 2017 21:13 PM

How can I accept player input using Coroutines, pausing execution of Unity while the player has not yet provided input? It seems like a simple problem, but I can't seem to figure it out. Here is my latest attempt. In this program I want to do some logic and pause in the middle, continuing only when the player has inputted some data. Someone please tell me I'm on the right track :O

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InputTester : MonoBehaviour
{
    int choice = -1; // valid choices for this example are 0 and 1

    void Start()
    {
        StartCoroutine(DoSomeLogic());
    }

    IEnumerator DoSomeLogic()
    {
        print("Starting...");
        print("Awaiting your choice - 0 or 1. :: ");
        // yield return StartCoroutine(WaitForKeyDown(KeyCode.Alpha0) || WaitForKeyDown(KeyCode.Alpha1));
        // how to combine these two into a single method that gives the player a choice?
        print("Continuing...");
        switch (choice)
        {
            // logic based on the choice
        }
    }

    IEnumerator WaitForKeyDown(KeyCode k)
    {
        while (!Input.GetKeyDown(k))
            yield return null;
        SetChoiceTo(k);
    }

    private void SetChoiceTo(KeyCode keyCode)
    {
        switch (keyCode)
        {
            case (KeyCode.Alpha0):
                choice = 0;
                break;
            case (KeyCode.Alpha1):
                choice = 1;
                break;
        }
        //StopAllCoroutines(); // how do I stop all the coroutines that accept player input?
        print(choice);
    }
}


Answers 1


try this, you simply give the WaitForKeyDown coroutine a list of keys to check, once it registers a key, it will exit the checking loop & terminate:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InputTester : MonoBehaviour {
    int choice = -1; // valid choices for this example are 0 and 1

    void Start() {
        StartCoroutine(DoSomeLogic());
    }

    IEnumerator DoSomeLogic() {
        print("Starting...");
        print("Awaiting your choice - 0 or 1. :: ");
        yield return StartCoroutine(WaitForKeyDown(new KeyCode[] { KeyCode.Alpha0, KeyCode.Alpha1 }));
        print("Continuing...");
        switch (choice) {
            // logic based on the choice
        }
    }

    IEnumerator WaitForKeyDown(KeyCode[] codes) {
        bool pressed = false;
        while (!pressed) {
            foreach (KeyCode k in codes) {
                if (Input.GetKey(k)) {
                    pressed = true;
                    SetChoiceTo(k);
                    break;
                }
            }
            yield return null; //you might want to only do this check once per frame -> yield return new WaitForEndOfFrame();
        }
    }

    private void SetChoiceTo(KeyCode keyCode) {
        switch (keyCode) {
            case (KeyCode.Alpha0):
                choice = 0;
                break;
            case (KeyCode.Alpha1):
                choice = 1;
                break;
        }
        print(choice);
    }
}
VoodaGod
VoodaGod
July 26, 2017 21:30 PM

Related Questions






NullReferenceException in StartCoroutine method

Updated November 25, 2016 08:05 AM