Space Shooter Challenge: Powerup Rarity and Weighted Spawn Systems
I’m now starting to create some reasonably strong powerups. I don’t want the user to have it too easy, so I created a rarity system so certain powerups spawn more frequently.
First, I had to assign a rarity to each powerup. To do so I created an int variable in the Powerup Script and created a Header for the inspector to show the value levels.
Now each powerup can be assigned a rarity in the Inspector. To pass this over to the Spawn Manager I created a return type method that when called, passes back the rarity variable.
For each powerup in the Spawn Manager’s array, I can call this method and assign it to a variable. To do so, the Powerup Script first needs to be accessed on each object using Get Component.
For each powerup, I now want to assign them to groups based on their rarity value. I can do so in a switch statement using _rarity as the variable. The groups I want to assign them to could make use of Arrays, but they’re difficult to add to at runtime without recreating the array each time something is added.
So instead I created three Lists, one for each rarity, to store the powerups.
Now for the switch statement, in each case, the variable obj storing the powerup can be added to the correct List.
This method needs to be called in Void Start, and to test the functionality, additional for each loops can be created to Debug.Log each object of the lists.
With that working, the SpawnRoutine method can now start on implementing the new system. The positions can stay as they are, but the code for getting a random index from the Powerup Array needs to change. Instead, I want to create yet another List, but to populate it, I need another return type method.
In the GetRarity method, I want it to return a GameObject List variable.
Within this method. I first want to create a random value. I opted for between 0 and 100 so I can correlate the system with percentages. I want Rare powerups to spawn 15% of the time, Uncommon 35%, and Common 50%.
To turn this into code, if and else if statements can be used, to check where the random value lies. In these statements, they simply return the corresponding Lists that were populated earlier.
This method gets called each cycle of the while loop in the SpawnPowerupRoutine, so it should generate a random number each time, and if it was to be run 100 times, the rare powerup list would be returned an average of 15 times and so forth.
With the random list being returned, I then need to access a random Game Object of that rarity. To do so, Random.Range can be used when calling an index of the List. Unlike Arrays using the .Length modifier, for Lists, the .Count modifier can be used.
Now the _randomPowerup Game Object variable can be Instantiated, with the finished method looking like the following.
With this, there are two levels of randomness as to what powerup is spawned, with one being percentage based for the rarity value, and then an even split amongst the objects of that particular rarity. Using the GetRarity return method, allows the Lists to dynamically change at run time, allowing the modular system to be expanded.
Check back tomorrow for an example on how to test this system is spawning the rarities accurately.