- Home /
Call Coroutine from value change event.
I have an event set up to fire a method when a bool value is changed. When I have the method and delegate set as voids they work perfectly, but then I set them as IEnumberators, the method doesn't get called.
public class BasicDefault : MonoBehaviour, ITower {
private bool _canFire;
private float _fireRate = 5;
private float _reloadTime;
// Links CanFire to _canFire and OnCanFireEvent
public bool CanFire {
get { return _canFire; }
set {
if (_canFire == value) {
return;
}
_canFire = value;
OnCanFireEvent?.Invoke(value);
}
}
public void Start () {
OnCanFireEvent += FireTimer;
}
public void Update () {
if (Input.GetKeyDown(KeyCode.B)) {
CanFire = !CanFire;
}
}
public void FindTarget () {
throw new System.NotImplementedException();
}
public void Fire () {
Debug.Log("Fire");
}
public IEnumerator FireTimer (bool canFire) {
Debug.Log($"FireTimer called | canFire: {canFire}");
if (canFire) {
while (true) {
_reloadTime += Time.deltaTime;
if (_reloadTime >= _fireRate) {
_reloadTime = 0;
Fire();
}
yield return null;
}
}
}
// Set up OnCanFireEvent
public delegate IEnumerator OnCanFireDelegate (bool value);
public static event OnCanFireDelegate OnCanFireEvent;
}
What I'm trying to do is have the tower wait 5 seconds after the CanFire bool being triggered, when true, then fire.
Answer by pako · Jan 14, 2018 at 07:22 PM
A quick note: you can't "call" a coroutine, you must use StartCoroutine(IEnumeratorName).
It's also better to use WaitForSeconds(5f) inside the coroutine to wait for 5 seconds, instead of accumulating Time.deltaTime.
https://docs.unity3d.com/ScriptReference/WaitForSeconds.html
In any case, I think you can just create a new event handler to subscribe to OnCanFireEvent
and inside the event handler, use StartCoroutine
.
e.g.
void FiringHandler(bool canFire)
{
StartCoroutine(FireTimer (canFire));
}
Of course you'd need to change your delegate accordingly;
Sorry, I can't give you a complete answer, since I must admit that I haven't seen this syntax before: OnCanFireEvent?.Invoke(value)
and I can't find any reference to decipher it.
OnCanFireEvent?.Invoke(value)
checks to make sure that OnCanFireEvent
isn't null, and if it isn't, call Invoke(value)