I have two different prefabs for a shield and health powerup that I want to randomly drop when an enemy dies. I dont what something to drop all the time as I have quite a few enemies on the screen at times. My code seems to work but surely there is a better way to handle this than a large if statement.

```
ranNumber = Random.Range(minNumber, maxNumber);
Debug.Log("Random number is " + ranNumber);
if (ranNumber == 1)
{
Instantiate(item1, transform.position, transform.rotation);
}
else if (ranNumber == 2)
{
return;
}
else if (ranNumber == 3)
{
return;
}
else if (ranNumber == 4)
{
Instantiate(item2, transform.position, transform.rotation);
}
else if (ranNumber == 5)
{
return;
}
else if (ranNumber == 6)
{
return;
}
```

Yes there is: make it all data driven, perhaps using ScriptableObjects.

Some good reading would be how to make a loot drop table, or a weighted probability table.

Here’s some more relevant reading:

ScriptableObject usage in RPGs:

https://discussions.unity.com/t/798767/2

https://discussions.unity.com/t/803356/2

Usage as a shared common data container:

https://www.youtube.com/watch?v=PVOVIxNxxeQ

So you have 6 possibilities (16.6% chance for each), but only two should do something. You only need to check two cases, and they can be the first two (or any of the possible numbers). Remember, Random.Range is max number exclusive, so to get 1-6, the range is (1, 7).

```
if (ranNumber == 1)
{
Instantiate(item1, transform.position, transform.rotation);
}
else if (ranNumber == 2)
{
Instantiate(item2, transform.position, transform.rotation);
}
else
{
return;
}
```

As mentioned, weighted probability tables are a good option too, with more flexibility. A simple one would be to get a random value between 0-100, then do checks for ranges. That allows different % for different events, like 50% for one, 20% for another, and 30% for a third, for example.

1 Like

Very simply with even odds:

```
GameObject[] options; // maintain an array field, plug in all options in the Inspector
GameObject go = options[Random.Range(0, options.Length)];
Instantiate(go, transform.position, transform.rotation);
```

For a weighted random as others have mentioned, you also want an array (or collection). But that’s more involved.

The steps are:

- assign each option a weight (eg 10, 20, 10, 5, 5) - ScriptableObjects as Kurt mentioned are great for this kind of data
- obtain the total weight by adding up all the weights (50)
- select a random value between zero and total weight (eg 37)
- select the option occupying that random value (the 3rd option).

2 Likes

Thanks, I think I am on the right path now thanks to everyone’s help.