Choosing random function

Say you have:

function Start() {
SlowSpawn();
MediumSpawn();
FastSpawn();
}

How would you randomly choose one of those functions to run?

Take it one step further and you could have:

function Start() {
for (var a : int = 0; a<AmountOfSlow; a++) {
yield WaitForSeconds(Random.Range(yieldTimeMin, yieldTimeMax)); 
SlowSpawn();
   }
for (var b : int = 0; b<AmountOfMedium; b++) {
yield WaitForSeconds(Random.Range(yieldTimeMin, yieldTimeMax)); 
MediumSpawn();
   }
for (var c : int = 0; c<AmountOfFast; c++) {
yield WaitForSeconds(Random.Range(yieldTimeMin, yieldTimeMax)); 
FastSpawn();
   }
}

and each one spawns a certain number of enemies.

Now how would you randomly choose a function to run, run that function, and then randomly choose another one of the functions until all the enemies have been spawned.

The problem with this is that if you write list of functions, of course it runs them all at once. But I want them to be running individually and one after the other.

Thanks for any help

3 Answers

3

Use an array of functions, and choose randomly from the array like you would with any other array:

var functions = [SlowSpawn, MediumSpawn, FastSpawn];

function Start () {
	functions[Random.Range(0, functions.Length)]();
}

Works great with the first part of my question but doesn't work with, answer or address the second and most important part of my question.

But how would you type cast a function? its not a string, and all the examples I've seen are dynamically typed. How would you script something like delegates, and having to typcast a function, that is statically typed, and will work with #pragma strict?

if else statements, Derp

thanks Eric that was really helpful, but how would i alter what functions are chosen in the inspector? out of curiosity

Functions won't show up in the inspector, so if you need that, you'd have to resort to if/then solutions (or switch/case) using enums or whatever.

Your friend in need is the class System.Random. It's a pseudo-random generator that you can use along with a switch to randomly execute one of the functions every time it's called. Here's an example (In C# though, hope you can translate):

System.Random randomizer = new System.Random();
int funcToChoose = randomizer.Next(3);

switch (funcToChoose)
{
    case 0:
        // Fire the first function
        break;
    case 1:
        // Fire the second function
        break;
    case 2:
        // Fire the third function
        break;
}

Unity's Random function is easier to use in most cases.

Ok, My question was pretty tough to understand exactly what I meant without me point at my screen so I stopped being lazy and wrote it myself. Couldn’t have done this without a part of Eric’s Answer though. Thank You Eric.

With this your able to have, say, three different types of enemies and then define how much you want each one to spawn. Then the script spawns each one, individually, and with a certain time between each spawn until there’s no more left to spawn.

That’s what my question was really trying to get at.

For anyone who runs into the same problem Use this as reference.

var SpawnPoints : Transform[]; 
var SlowEnemy : GameObject; 
var MediumEnemy : GameObject; 
var FastEnemy : GameObject; 
var AmountOfEnemiesTotal : int;
var WaitTime : int = 1;  
var NumberOfSlowEnemies : int;
var NumberOfMediumEnemies : int;
var NumberOfFastEnemies : int;
var SlowTrue : boolean = true;
var MediumTrue : boolean = true;
var FastTrue : boolean = true;
private var functions = [SlowSpawn, MediumSpawn, FastSpawn];


function FixedUpdate(){
if (NumberOfSlowEnemies == 0){
SlowTrue = false;
}
if (NumberOfMediumEnemies == 0){
MediumTrue = false;
}
if (NumberOfFastEnemies == 0){
FastTrue = false;
}
if (SlowTrue == false){
functions = [MediumSpawn, FastSpawn];
}
if (MediumTrue == false){
functions = [FastSpawn, FastSpawn];
}
if (FastTrue == false){
functions = [MediumSpawn, SlowSpawn];
}
if (SlowTrue == false && MediumTrue == false){
functions = [FastSpawn];
}
if (SlowTrue == false && FastTrue == false){
functions = [MediumSpawn];
}
if (MediumTrue == false && FastTrue == false){
functions = [SlowSpawn];
}
if (MediumTrue == false && FastTrue == false && SlowTrue == false){
StopAllCoroutines();
}
}

function Start() {
AmountOfEnemiesTotal = NumberOfSlowEnemies+NumberOfMediumEnemies+NumberOfFastEnemies;
StartCoroutine("FunctionArc");
}

function FunctionArc(){
yield WaitForSeconds(WaitTime);
if (AmountOfEnemiesTotal>0){
StartCoroutine("ChooseFunction");
}
}

function ChooseFunction(){
functions[Random.Range(0, functions.Length)]();
StopCoroutine("ChooseFunction");
}


function SlowPass(){
if (SlowTrue && NumberOfSlowEnemies>0){
StartCoroutine("SlowSpawn");
   }
}

function MediumPass(){
if (MediumTrue && NumberOfMediumEnemies>0){
StartCoroutine("MediumSpawn");
   }
}


function FastPass(){
if (FastTrue && NumberOfFastEnemies>0){
StartCoroutine("FastSpawn");
   }
}


function SlowSpawn() { 
      NumberOfSlowEnemies -= 1;
      var pos: Transform = SpawnPoints[Random.Range(0, SpawnPoints.length)]; 
      Instantiate(SlowEnemy, pos.position, pos.rotation); 
      StartCoroutine("FunctionArc"); 
      StopCoroutine("SlowSpawn");
   }

function MediumSpawn() {
      NumberOfMediumEnemies -= 1;
      var pos2: Transform = SpawnPoints[Random.Range(0, SpawnPoints.length)]; 
      Instantiate(MediumEnemy, pos2.position, pos2.rotation); 
      StartCoroutine("FunctionArc"); 
      StopCoroutine("MediumSpawn");
   }  

function FastSpawn() { 
      NumberOfFastEnemies -= 1;
      var pos3: Transform = SpawnPoints[Random.Range(0, SpawnPoints.length)]; 
      Instantiate(FastEnemy, pos3.position, pos3.rotation); 
      StartCoroutine("FunctionArc"); 
      StopCoroutine("FastSpawn");
   }

If you couldn't have done it without eric's answer, you should've posted this as a comment and accepted his answer so he gets credit for it... just sayin.

Gave him a thumbs up, just marked this one right because its the exact answer to the question. This is a database right?

Your full solution is a direct extension of Eric's answer. You can have a +1 on the Question for it being a good one.