一次捕获和处理多个键盘输入

Catching and processing multiple keyboard inputs at once

我正在使用 DryWetMIDI 库开发一款依赖钢琴键盘 MIDI 输入的 Unity 游戏。我必须检测和弦何时被演奏并将和弦作为一个整体来处理。

目前我的做法是在第一个音符按下后等待0.1秒,将这段时间按下的所有音符放入一个列表中。然后我处理这个列表。但是,当我尝试使用 Coroutine 时,WaitThenNotify() 中的代码永远不会执行。

这是代码。

    private List<NoteOnEvent> inputs = new List<NoteOnEvent>();
    private bool waiting = false;

    // Start is called before the first frame update
    void Start() {
        if ((InputDevice.GetAll() is null)) {
            return;
        }
        inputDevice = InputDevice.GetById(0);
        inputDevice.EventReceived += OnEventReceived;
        inputDevice.StartEventsListening();
    }

    private void OnEventReceived(object sender, MidiEventReceivedEventArgs e) {
        if (e.Event.EventType.Equals(MidiEventType.NoteOn)) {
            inputs.Add((NoteOnEvent)e.Event);
        }
        if (!waiting) {
            // catch all inputs within 0.1 seconds, for chords.
            waiting = true;
            StartCoroutine(WaitThenNotify());
        }
    }
    
    IEnumerator WaitThenNotify() {
        yield return new WaitForSeconds(0.1f);
        print("here");
        
        PianoPressObserver.UpdateSubjects(inputs);
        waiting = false;
        inputs.Clear();
    }

谁能告诉我为什么会这样?或者更好的是,是否有更好的捕捉和弦输入的方法?

我是 DryWetMIDI 的作者。我想你的问题与多线程有关。 OnEventReceived 将从内部 WinMM 线程调用。但据我所知,在 Unity 中你应该在 Unity 主线程上启动协程。所以你需要从Unity主线程调用StartCoroutine

请阅读库文档的这一部分:https://melanchall.github.io/drywetmidi/articles/playback/Common-problems.html#setactive-can-only-be-called-from-the-main-thread-in-unity

相关问题:https://answers.unity.com/questions/1670686/startcoroutine-can-only-be-called-from-the-main-th.html