So you want that this code from the supplied link:
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
public class SelfDestruct : MonoBehaviour {
public GameObject explosion;
private float shake = 0.2f;
private AudioSource audioSource;
void Awake ()
{
audioSource = GetComponent <AudioSource>();
}
void OnEnable ()
{
EventManager.StartListening ("Destroy", Destroy);
}
void OnDisable ()
{
EventManager.StopListening ("Destroy", Destroy);
}
void Destroy ()
{
EventManager.StopListening ("Destroy", Destroy);
StartCoroutine (DestroyNow());
}
IEnumerator DestroyNow()
{
yield return new WaitForSeconds (Random.Range (0.0f, 1.0f));
audioSource.pitch = Random.Range (0.75f, 1.75f);
audioSource.Play ();
float startTime = 0;
float shakeTime = Random.Range (1.0f, 3.0f);
while (startTime < shakeTime)
{
transform.Translate (Random.Range (-shake, shake), 0.0f, Random.Range (-shake, shake));
transform.Rotate ( 0.0f, Random.Range (-shake * 100, shake * 100), 0.0f);
startTime += Time.deltaTime;
yield return null;
}
Instantiate (explosion, transform.position, transform.rotation);
Destroy (gameObject);
}
}
Could rather work as:
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
public class SelfDestruct : MonoBehaviour {
public GameObject explosion;
private float shake = 0.2f;
private AudioSource audioSource;
void Awake ()
{
audioSource = GetComponent <AudioSource>();
}
void OnEnable ()
{
EventManager.StartListening ("Destroy", DestroyNow);
}
void OnDisable ()
{
EventManager.StopListening ("Destroy", DestroyNow);
}
IEnumerator DestroyNow()
{
EventManager.StopListening ("Destroy", DestroyNow);
yield return new WaitForSeconds (Random.Range (0.0f, 1.0f));
audioSource.pitch = Random.Range (0.75f, 1.75f);
audioSource.Play ();
float startTime = 0;
float shakeTime = Random.Range (1.0f, 3.0f);
while (startTime < shakeTime)
{
transform.Translate (Random.Range (-shake, shake), 0.0f, Random.Range (-shake, shake));
transform.Rotate ( 0.0f, Random.Range (-shake * 100, shake * 100), 0.0f);
startTime += Time.deltaTime;
yield return null;
}
Instantiate (explosion, transform.position, transform.rotation);
Destroy (gameObject);
}
}
???
Well for starters, you’re going to also have to pass in the MonoBehaviour that will run the coroutine (less you want to use some global one).
Why does this sound dirty?
Why not? I use them all the time.
Sure add this to the EventManager for starting listening:
public static void StartListening (string eventName, MonoBehaviour handle, System.Func<IEnumerator> coroutineListener)
{
StartListening(eventName, () => {
handle.StartCoroutine(coroutineListener);
});
}
But since it uses an anonymous delegate, removing it isn’t as straight forward. You’ll need to track the an association between the coroutine and created delegate. Which if you really want to do I can go into further detail about…
but…
I personally think you should look for a different way of doing such things. This is honestly a very weak method of doing things. And I don’t see the need of adding coroutine support to it… if you want coroutines, just do it the way the example code from the link you supplied above does it.
It’s perfectly valid code, and doesn’t require a whole bunch of extra state tracking to handle StopListening.