Forum begins after the advertisement:
[Part 2] Help making a “rarity”system for PropRandomizer
Home › Forums › Video Game Tutorial Series › Creating a Rogue-like Shoot-em Up in Unity › [Part 2] Help making a “rarity”system for PropRandomizer
- This topic has 2 replies, 3 voices, and was last updated 4 days, 16 hours ago by
Terence.
-
AuthorPosts
-
May 28, 2025 at 3:04 am #18214::
i have been struggling with a system that separates the props in rarities and then spawn them based into rarities. Example: Common (60%) Uncommon (20%) Rare (10%) Epic (6%) Legendary (4%)
in my approach each rarity would be a list and a function would roll the dice, pick a list based on the number rolled and return that list to the SpawnProps function so it would pick a random object into that list and spawn it
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PropRandomizer : MonoBehaviour { public List<GameObject> propSpawnPoints; [Header("Props by Rarity")] public List<GameObject> commonProps; // 60% chance public List<GameObject> uncommonProps; // 20% chance public List<GameObject> rareProps; // 10% chance public List<GameObject> epicProps; // 6% chance public List<GameObject> legendaryProps; // 4% chance void Start() { SpawnProps(); } GameObject GetRandomPropByRarity() { int roll = Random.Range(0, 100); if (roll < 60 && commonProps.Count > 0) return commonProps[Random.Range(0, commonProps.Count)]; if (roll < 80 && uncommonProps.Count > 0) return uncommonProps[Random.Range(0, uncommonProps.Count)]; if (roll < 90 && rareProps.Count > 0) return rareProps[Random.Range(0, rareProps.Count)]; if (roll < 96 && epicProps.Count > 0) return epicProps[Random.Range(0, epicProps.Count)]; if (legendaryProps.Count > 0) return legendaryProps[Random.Range(0, legendaryProps.Count)]; if (commonProps.Count > 0) return commonProps[Random.Range(0, commonProps.Count)]; return null; } void SpawnProps() { foreach (GameObject sp in propSpawnPoints) { GameObject selectedProp = GetRandomPropByRarity(); if (selectedProp != null) { GameObject prop = Instantiate(selectedProp, sp.transform.position, Quaternion.identity); prop.transform.parent = sp.transform; } } } }
I made it like this, and tried some other different approaches, but none work. When i start the game only the inicial props spawn, the others dont…
The original code of the series looks like this
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PropRandomizer : MonoBehaviour { public List<GameObject> propSpawnPoints; public List<GameObject> propPrefabs; void Start() { SpawnProps(); } void SpawnProps() { foreach (GameObject sp in propSpawnPoints) { int rand = Random.Range(0, propPrefabs.Count); GameObject prop = Instantiate(propPrefabs[rand], sp.transform.position, Quaternion.identity); prop.transform.parent = sp.transform; } } }
has upvoted this post. May 29, 2025 at 1:44 am #18220::@jukers good to see you back here.
I don’t see anything wrong with your code. The first thing I would do is to add a print function to see if the new code is running. Specifically:
GameObject GetRandomPropByRarity() { int roll = Random.Range(0, 100); print("GetRandomPropByRarity() called with roll of " + roll); if (roll < 60 && commonProps.Count > 0) return commonProps[Random.Range(0, commonProps.Count)]; if (roll < 80 && uncommonProps.Count > 0) return uncommonProps[Random.Range(0, uncommonProps.Count)]; if (roll < 90 && rareProps.Count > 0) return rareProps[Random.Range(0, rareProps.Count)]; if (roll < 96 && epicProps.Count > 0) return epicProps[Random.Range(0, epicProps.Count)]; if (legendaryProps.Count > 0) return legendaryProps[Random.Range(0, legendaryProps.Count)]; if (commonProps.Count > 0) return commonProps[Random.Range(0, commonProps.Count)]; return null; }
@alp.apustaja can you check his code and see if there’s anything wrong?
May 29, 2025 at 1:51 am #18221::It looks like your code is structured correctly, but I notice a few things you might want to check or improve upon:
-
Print Statement: Ensure that the
print
function you are using is appropriate for your environment. If you are using Unity, you should useDebug.Log
instead ofprint
. So it should look like this:Debug.Log("GetRandomPropByRarity() called with roll of " + roll);
-
Rarity Distribution: Double-check your rarity distribution logic. Your current setup has the following probabilities:
- 60% chance for common
- 20% chance for uncommon (60% to 80%)
- 10% chance for rare (80% to 90%)
- 6% chance for epic (90% to 96%)
- 4% chance for legendary (96% to 100%)
Ensure this distribution aligns with your game’s design. You might want to adjust the percentages if they don’t reflect the desired rarity weights.
-
Return Statement Logic: If all rarity checks fail and
commonProps
is empty, your function returnsnull
. Make sure your calling code can handle anull
return value appropriately. -
Thread-Safety: If you are accessing
commonProps
,uncommonProps
,rareProps
,epicProps
, andlegendaryProps
from multiple threads, consider locking or using concurrent collections to avoid race conditions. -
Debugging: If you still have issues, try adding more debug statements to log the counts of each property list before making the rolls to ensure they are populated correctly.
Here’s the modified code snippet with the
Debug.Log
statement:GameObject GetRandomPropByRarity() { int roll = Random.Range(0, 100); Debug.Log("GetRandomPropByRarity() called with roll of " + roll); if (roll 0) return commonProps[Random.Range(0, commonProps.Count)]; if (roll 0) return uncommonProps[Random.Range(0, uncommonProps.Count)]; if (roll 0) return rareProps[Random.Range(0, rareProps.Count)]; if (roll 0) return epicProps[Random.Range(0, epicProps.Count)]; if (legendaryProps.Count > 0) return legendaryProps[Random.Range(0, legendaryProps.Count)]; if (commonProps.Count > 0) return commonProps[Random.Range(0, commonProps.Count)]; return null; }
Try out these suggestions and see if it resolves the issues you’re encountering!
May 29, 2025 at 1:52 am #18222 -
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: