Player Feedback: Balanced Spawned
Another common feedback that I was requested to add was a more balanced spawn system. There would be situations where the player wouldn’t get enough ammo pick ups and would be basically playing the entire game without ammo.
To fix this issue, we will be adding an weighted item system where we allow certain randomize powerup to show up more than others. We will require the Spawn Manager script.
Understanding the Logic:
Firstly, we have to accept that Unity’s script doesn’t understand percentages. Instead it accepts numbers. To break it down even further, we can pretend that we are picking items out of a hat. Within the hat, we have 10 items in total, and within those 10 items it is divided by 3 types, “Ammo”, “Health”, “Special Ammo”. If we want “Ammo” to show up more offend than “Health” and “Special Ammo” we simply have more ammo items than the other two types. Say we want 7 Ammo, 2 Health and 1 Special Ammo. In the hat it shall look like this:
Hat = Ammo / Ammo / Ammo / Ammo / Ammo / Ammo /Ammo / Health / Health / Special Ammo
To our understanding, Ammo would have about 70% chance of being picked, while Health is 20% and Special Ammo would be the remaining 10%. But in Unity it is based on amount.
The Spawn Manager Script:
In the spawn manager script we are going to locate the section where we instantiate the powerup. We are going to delete everything related to the current setup since we will be implementing the new system.
We are then going to create several new handles. First will be an Integer variable table that will state the “percentage” and total items within the “Hat”. Referencing the example above, if you have 3 powerups then you will have 3 variables within the table. If you have more, simply expand the total amount. As for the “percentage” this is defined as the number.
pro tip: Unity will always, always read the variables top-down or left to right. So having the proper order is critical, therefore having the highest amount go first is the proper method. (ie. 70, 20, 10) it can NEVER be ( 20, 70, 10) or any other sequence.
Next we will create another integer variable for “total”. This will show us in the inspector the grand total of all the items within the table(hat) adds up to. Although it is within best practice to have the grand total equal to 100 or 1000, it doesn’t always have to be. It just becomes easy to calculate the percentage later on.
Finally we will have an public integer for Random number. This integer will be the variable which controls which number is called upon the total(hat).
In my example, I will be writing all of my codes within a private method, but all these codes can be implemented within the start method as well.
Within my method, I first start with a foreach loop where I calculate the grand total from the power up table.
Then I have the randomNumbers generate a number from zero to the grand total.
Then I finish off the method by adding an for loop with the infamous: (int i = o; i< table_powerups.Length; i++)
Within the for loop, I have an if statement where if the random number generated is less than the the number provided by the table, I would spawn the powerup at a random generated location within the scene. I also place an return function here so the script only runs once.
Else, I would continue to subtract the randomly generated number until it hits a number shown within the table.
(ie. If the generated number was 80, and my highest table number is 70. I would need to continue to subtract the 80 until it is under the 70 or lower number.)
So the total script looks like this when you are finished.
Since I wrote all my script within a private method, I will need to call it within my IEnumerator function which controls when I can spawn the powerups.
Linking the Spawned powerUps with the Balanced spawn system:
Now that we got our system up and running, its time to link the power up prefabs to the newly created system. To do this, I created a “List” of Game Objects called power ups.
This allows me to assign the power up prefabs into the desired slot.
Remember that Unity likes to read top to down, therefore in this example, Unity would start with element zero. Therefore, since we have written that Element 0 is going to have the most common spawn, we can assign the Ammo pick up prefab to element zero.