2
\$\begingroup\$

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);
    }
}
\$\endgroup\$
  • \$\begingroup\$ Well, you can't WaitForKeyDown() as an enumerator the way you have it coded. You would first check the one key, then wait a frame, then check the other key, then wait a frame. \$\endgroup\$ – Draco18s Jul 26 '17 at 20:46
2
\$\begingroup\$

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);
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.