- Home /
Calling a random function in a Coroutine
Hello everyone,
I was wondering if there is a way to stock functions on a List that a Coroutine can call randomly ?
In my case I want to randomly express between a list of five emotions that are basically like this:
void Happy()
{
do something
}
void Sad()
{
do something
}
...
And I would like to use them on something like that :
IEnumerator RandomEmotion()
{
yield return new WaitForSeconds(Random.Range(5, 10));
Random.Range(Emotion1, Emotion5);
}
Sorry, I'm not very familiar with Lists so if anyone have a idea on how can I proceed to achieve that that's would be wonderful :)
Antoine
Answer by Hellium · Jan 08, 2019 at 03:00 PM
Supposing all the functions share the same signature (returning void, with no parameter)
private System.Action[] emotions ;
void Happy()
{
do something
}
void Sad()
{
do something
}
void Start()
{
emotions = new System.Action[]
{
Happy,
Sad,
...
};
}
IEnumerator RandomEmotion()
{
yield return new WaitForSeconds(Random.Range(5, 10));
int index = Random.Range(0, emotions.Length);
if( emotions[index] != null ) emotions[index]();
}
Works like a charm, thank you !
What's exactly the difference between System.Action and a standard List?
They aren't comparable. That's an array containing instances of System.Action, but you could also have a List of that type. You can think of System.Action as a special type that allows you to pass functions as variables, as long as they don't return anything.
void SomeFunction()
{
Debug.Log("Hello");
}
void SomeOtherFunction(System.Action callback)
{
callback();
}
// Called with
SomeOtherFunction(SomeFunction);
You can also specify parameter types to use functions more generally. They're particularly useful if you need to wait for something like a Web Request:
void OnResponse(string response)
{
Debug.Log(response);
}
IEnumerator LongWebRequest(System.Action<string> callback)
{
var request = UnityWebRequest.Get("https://www.google.com");
yield return request.SendWebRequest();
callback(request.downloadHandler.text);
}
// Which you'd call with
StartCoroutine(LongWebRequest(this.OnResponse));