Search Unity

ScriptableObjects with weighted randomness

Discussion in 'Scripting' started by rasmusnielsen, Nov 1, 2020.

  1. rasmusnielsen

    rasmusnielsen

    Joined:
    Feb 7, 2020
    Posts:
    11
    Hi friends!

    I'm making a game and I want to show some "power-ups" randomly based on a weighted value stored with the powerup.

    Those things are stored in a ScriptableObject.

    Code (CSharp):
    1. public class ScriptablePowerUp : ScriptableObject
    2. {
    3.     public string name;
    4.     public string identifier;
    5.     public string description;
    6.     public int cost;
    7.     public int rarety;
    8.     public Sprite cartrdigeIcon;
    9. }
    10.  
    My plan is to sum up all the rarities and with that make a random roll from 0 to the total and then check if the random number was in between those numbers, if yes, then spawn that object. Hopefully that makes sense?

    My question is now, how do I do this with a scriptable object? Getting all the values etc.

    I have this code from a previous project which works fine, but doesn't use scriptableobjects and I simply can't figure out how to convert it.

    Code (CSharp):
    1. public class Powerup : MonoBehaviour
    2. {
    3.     [SerializeField]
    4.     public float LootRoll;  
    5.    
    6.     private float calc = 0;
    7.     private float newmincalc;
    8.     public float totalWeight;
    9.     [System.Serializable]
    10.     public class LootItems
    11.     {
    12.         public string name;
    13.         public GameObject itemDropped;
    14.         public int dropWeight;
    15.        
    16.         //[HideInInspector]
    17.         public float minRollRange;
    18.         //[HideInInspector]
    19.         public float maxRollRange;
    20.     }
    21.  
    22.     public List <LootItems> LootTable = new List <LootItems> ();
    23.  
    24.     // Start is called before the first frame update
    25.     void Start()
    26.     {
    27.    
    28.  
    29.  
    30.     // Get total sum of weights
    31.     totalWeight = 0;  
    32.     foreach (var LootItems in LootTable) {
    33.        totalWeight += LootItems.dropWeight;
    34.     }
    35.    
    36.     // Looping through again to create if statements
    37.     int i = 0;
    38.     foreach (var LootItems in LootTable) {  
    39.         i++;
    40.        
    41.         calc = calc + LootItems.dropWeight;    
    42.         newmincalc = calc - LootItems.dropWeight + 1;
    43.        
    44.         if (i == 1){
    45.             LootItems.minRollRange = 0;
    46.             LootItems.maxRollRange = calc;
    47.             //Debug.Log("Item #" + i + ", Between 0 - " + calc);
    48.         }else {
    49.             LootItems.minRollRange = newmincalc;
    50.             LootItems.maxRollRange = calc;
    51.             //Debug.Log("Item #" + i + ", Between " + newmincalc + " - " + calc);
    52.         }
    53.     }
    54.  
    55. DropLoot();
    56.  
    57.     }
    58.  
    59.    public void DropLoot(){
    60.  
    61.         LootRoll = Mathf.Round(Random.Range(0,totalWeight));
    62.         Debug.Log("I rolled " + LootRoll);
    63.  
    64.         //Debug.Log(totalWeight);
    65.        
    66.         foreach (var LootItems in LootTable) {
    67.          if (LootRoll >= LootItems.minRollRange && LootRoll <= LootItems.maxRollRange){
    68.             //Debug.Log(LootItems.name);
    69.            
    70.             Instantiate(LootItems.itemDropped, gameObject.transform.position, Quaternion.identity);
    71.             //Instantiate(LootItems.itemDropped, new Vector2(0,0), Quaternion.identity);
    72.         }
    73.        
    74.     }
    75.    
    76.    }
    77.  
    78. }
    79.  
    Hope you
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,911
    Change your List<LootItem> to a List<ScriptablePowerUp>
     
  3. rasmusnielsen

    rasmusnielsen

    Joined:
    Feb 7, 2020
    Posts:
    11
    Like this? Does nothing atm.

    Code (CSharp):
    1. public List <ScriptablePowerUp> LootTable = new List <ScriptablePowerUp>();
     
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,911
    Yes. After that, fix the rest of the code to work with that new data type, and finally assign your SOs into that list in the inspector.
     
  5. rasmusnielsen

    rasmusnielsen

    Joined:
    Feb 7, 2020
    Posts:
    11
    That absolutely worked. Thank you so much!