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\$
1
  • \$\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\$ Commented Jul 26, 2017 at 20:46

1 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .