First of all, I wouldn't use a coroutine to achieve that, I'll simply use an EventHandler or a direct delegate, but if your requeriment is to "make a coroutine" I'll aproach it like this:
using System.Collections;
using UnityEngine;
public class SOExample: MonoBehaviour
{
public bool OnEventCalled = false;
private void Start()
{
//Starts coroutine to wait until OnEvent
StartCoroutine(MyOwnCoroutine());
}
public void OnLibraryEvent(string data)
{
Debug.Log("OnLibraryEvent");
OnEventCalled = true;
}
private IEnumerator MyOwnCoroutine()
{
Debug.Log("Waiting");
yield return new WaitUntil(() => OnEventCalled);
Debug.Log("Do stuff with received event");
}
}
The key is to use the WaitUntil yield instruction, and use a custom flag, in this example I've used a simple boolean, but you can use whatever you want as a delegate.
Remember to set to false again the flag if you want to reuse it!
If you want to go further and create your own custom yield instruction try with CustomYieldInstruction class, but is similar under the hood.
EDIT: Can probably be better implemented but this aproximation with CustomYieldInstruction currently works:
public class WaitForEventOrTimeout : CustomYieldInstruction
{
//used to call StartCoroutine inside this class
private MonoBehaviour mono = null;
private Func<bool> checkIfEventIsTriggered = null;
private float waitingTime = 0;
private bool timeoutTriggered = false;
//this will be checked continously while returns true
public override bool keepWaiting
{
get
{
return !timeoutTriggered && !checkIfEventIsTriggered();
}
}
//Constructor called when "new"
public WaitForEventOrTimeout(MonoBehaviour mono, Func<bool> checkIfEventIsTriggered, float waitingTime)
{
this.mono = mono;
this.waitingTime = waitingTime;
this.checkIfEventIsTriggered = checkIfEventIsTriggered;
//Starts countdown to timeout
mono.StartCoroutine(WaitForTimeout());
}
private IEnumerator WaitForTimeout()
{
yield return new WaitForSeconds(waitingTime);
timeoutTriggered = true;
}
}
Use it like:
using System;
using System.Collections;
using UnityEngine;
public class SOO : MonoBehaviour
{
private bool _onEvent = false;
public bool OnEvent() => _onEvent;
private void Start()
{
//Starts coroutine to wait until OnWaitForEventOrTimeout
StartCoroutine(MyOwnCoroutine());
}
public void OnLibraryEvent()
{
//When LibraryEvent is called, set the flag to true
_onEvent = true;
}
private IEnumerator MyOwnCoroutine()
{
Debug.Log("Waiting");
yield return new WaitForEventOrTimeout(this, OnEvent, 4);
Debug.Log("Do stuff with received event");
//Reset flag
_onEvent = false;
}
}