Randomize the drop timing (SOLVED)

Beginner that has made a prototype with an object that drops items. Thought need help to figure out how to randomize the drop timing. Help appreciated!

EDIT: Thanks for all help!

5403945–548514–Snowball.cs (463 Bytes)
5403945–548517–SnowballPicker.cs (1.11 KB)
5403945–548520–SnowMan.cs (1.1 KB)
5403945–548523–Duplicate.cs (634 Bytes)
5403945–548526–Hands.cs (1.07 KB)

Wherever you choose how long to wait, instead of putting in a constant value of seconds, use Random.Range(); to choose a variable number of seconds.

When your script starts, you call InvokeRepeating("DropSnowball", 2f, secondsBetweenAppleDrops).

First thing to point out is that the function InvokeRepeating, according to the documentation, is InvokeRepeating(methodName, time, repeatRate) so I’m not sure your variable secondsBetweenAppleDrops is really doing what you expect. Should it instead be InvokeRepeating("DropSnowball", secondsBetweenAppleDrops, 2), which would drop two … snowball / apples with secondsBetweenAppleDrops time between them?

Anyways, if you are trying to randomize the time between drops, you probably don’t want to do it with the InvokeRepeating call, since every time you invoke that method (drop snowball) it will repeat with the same amount of time. You are repeating the time between drops, which sounds exactly what you are trying to avoid.

So to pseudocode what you have here, you are saying

When I start, I plan on drop a snowball every X seconds, Y times.

It doesn’t give you the flexibility to randomize between drops. And I think what you want to say instead is something like

When I start, I am going to drop a snowball in Random seconds.
After it’s dropped, I am going to drop another snowball in Random seconds.
I am going to do this Y times.

So, what you could do is in your start function call Invoke(“DropSnowball”, Random.Range(minRandomTime, maxRandomTime);

And then in your DropSnowball function, you could once again call Invoke("DropSnowball", Random.Range(minRandomTime, maxRandomTime);

Of course then, it will just drop snowballs or apples forever, so you will also want to check to make sure you only do it the number of times you want. So, if you had an integer like “numSnowballsToDrop = 2”, then you would want to wrap your invoke with something like

if(numSnowballsToDrop > 0)
{
  Invoke(...);
  numSnowballsToDrop--;
}

That’s not a really elegant solution, since it puts some of the responsibility of dropping additional snowballs into the logic that is also doing the dropping, and that seems irresponsible. So an alternative solution would be, in your start function, to do something like this

float sumTime = 0f; // The cumulative time of snowball / apple drops
for(int i = 0; i < numSnowballsToDrop; i++) // Do this numSnowballsToDrop times
{
  sumTime = sumTime + Random.Range(minRandomTime, maxRandomTime);
  Invoke("DropSnowball", sumTime);
}

And now you’ve taken the logic of spawning snowballs out of the function that actually does the creation, and it’s all set up for you at start.