Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Accessing Multiple Types of Data through 1 variable

Discussion in 'Scripting' started by Baken40, Nov 15, 2022.

  1. Baken40

    Baken40

    Joined:
    Feb 27, 2019
    Posts:
    3
    I am probably way overthinking this as I tend to do, but here is my basic situation.

    I have 3 Scriptable Objects : Player Stats, Weapon Stats and Upgrade Stats

    Player Stats are base stats (move speed, health, etc)
    Weapon Stats are just that (Damage, Recharge time, range, etc)
    Upgrade stats are on objects that modify either the player stats OR the weapon stats OR both

    I have a constructor and I have all of the variables from player and weapon in there, 3 functions to update said stats (one for player setup, one for weapon setup and one to upgrade).

    My issue is that I want to be able to access the data within the constructor by having a simple Get function that returns the data.

    I tried creating a STATS scriptable object that the constructor built, but even though the code did not have errors, it did not actually update the data.

    Now that I have typed this all out, would it just make sense access the constructor through the player?

    eg

    PLAYER SCRIPT (Instanced so it is accessible for read only)
    private PlayerStats playerStats;
    ...
    public GameStats gameStats {get; private set;}
    ...
    private void Start()
    {
    gameStats = new GameStats (playerStats)
    }

    public GameStats GetStats()
    {
    return gameStats;
    }

    RANDOM SCRIPT

    private float weaponDamage;

    start()
    {
    weaponDamage = PlayerScript.Instance.GetStats().damage
    }


    I was hoping to decouple this by having a "variable" stored that contained all of the stats that was independent of the player so that it could be accessed if the player was not in the scene for any reason.

    Am I over thinking this and making it more complicated than it should be? I am still relatively newish to game dev. Appreciate any help!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,963
    A constructor for a ScriptableObject? That won't work.

    You can NEVER use the
    new
    keyword to make MonoBehaviour- or ScriptableObject- derived classes.

    You must use ScriptableObject.CreateInstance<T>() to make your SO, then you can fill it out however you like.

    I think you were just typing here in the forum, but keep in mind if you expect the above method to be called by Unity, it won't be. Go look at the proper spelling and capitalization.
     
  3. Baken40

    Baken40

    Joined:
    Feb 27, 2019
    Posts:
    3
    I think I didn't explain right, or again, I am overthinking. Here is the code (not exact because I am at work and the code is on my PC at home). Ignore syntax like capital and spelling as that is all correct since the editor auto-populates that on my home PC, this is just me trying to get out what I mean :)

    Code (CSharp):
    1. //Constructor class
    2. public class GameStats
    3. {
    4.     private MasterStats currentStats;
    5.  
    6.  
    7.     public GameStats (PlayerStats playerStats)
    8.     {
    9.         currentStats = playerStats; //This is what I want, although I assume it doesn't work
    10.  
    11.         //So i did this:
    12.  
    13.         currentStats.damage = playerStats.damage;
    14.         currentStats.bloodLossRate = playerStats.bloodLossRate;
    15.         currentStats.infectionGrowthRate = playerStats.infectionGrowthRate;
    16.         currentStats.soulGain = playerStats.soulGain;
    17.  
    18.     }
    19.  
    20.     public void EquipWeapon(WeaponStats weapon)
    21.     {
    22.         currentStats.damage = weapon.damage;
    23.         currentStats.range = weapon.range;
    24.         currentStats.rechargeTime = weapon.rechargeTime;
    25.     }
    26.  
    27.     public void EquipPassiveWeapon(PassiveStats passive)
    28.     {
    29.         currentStats.numberOfObjects = passive.numberOfObjects;
    30.         currentStats.damageOverTimeValue = passive.damageOverTimeValue;
    31.     }
    32.  
    33.     public void UpgradeStats(UpgradeStats upgrade)
    34.     {
    35.         currentStats.damage += upgradeStats.damage;
    36.         //for all of the variables in the game that are upgradable
    37.     }
    38.  
    39.     public MasterStats GetStats()
    40.     {
    41.         return currentStats;
    42.     }
    43. }
    44.  
    45.     //ON MY PLAYERHANDLER CLASS
    46.     public class PlayerHandler : Monobehavior
    47.     {
    48.         public static PlayerHandler Instance {get; private set;}
    49.  
    50.         [SerializableField] private PlayerStats playerStats;
    51.         public GameStats gameStats {get; private set;}
    52.  
    53.         private void Awake()
    54.         {
    55.             Instance = this;
    56.         }
    57.  
    58.         private void Start()
    59.         {
    60.             gameStats = new GameStats(playerStats);
    61.         }
    62.  
    63.     }
    64.  
    65.     public class SomeOtherClass : Monobehavior
    66.     {
    67.  
    68.         private void OnCollisionEnter2D(Collision2d other)
    69.         {
    70.             if(other.TryGetComponent(IDamageable))
    71.             {
    72.                 IDamageable damageable = other.GetComponent(IDamageable);
    73.                 other.TakeDamage(PlayerStats.Instance.gameStats.GetStats().damage);
    74.  
    75.                 //this line of code above is what I want to accomplish.  I want to store and update
    76.                 //all of the various stats for the game in one place and then access them
    77.                 //when needed.
    78.             }
    79.         }
    80.     }
    81.     [CreateAssetMenu]
    82.     public class MasterStats: ScriptableObject
    83.     {
    84.         public float bloodLossRate;
    85.         public float soulGain;
    86.         public float infectionGrowthRate;
    87.         public float damage;
    88.         public float range;
    89.         public float rechargeTime;
    90.         public float damageOverTimeValue;
    91.         public int numberOfObjects;
    92.      
    93.     } //should I just make this a struct?    I read that structs should be for small amounts of data,
    94. //or maybe just a class that doesn't inherit from monobehavior, I think i have 10 or 12 "stats"
    95. //that I want to store in a centralized variable for ease of access
    96.  
    97.   public class MasterStats
    98.     {
    99.         public float bloodLossRate;
    100.         public float soulGain;
    101.         public float infectionGrowthRate;
    102.         public float damage;
    103.         public float range;
    104.         public float rechargeTime;
    105.         public float damageOverTimeValue;
    106.         public int numberOfObjects;
    107.      
    108.     }
    109.  
     
    Last edited: Nov 15, 2022
  4. Baken40

    Baken40

    Joined:
    Feb 27, 2019
    Posts:
    3
    I think I may have answered my own question when I was "recoding" this.
    Code (CSharp):
    1. //Constructor class
    2. public class GameStats
    3. {
    4.     public class MasterStats
    5.     {
    6.         public float bloodLossRate;
    7.         public float soulGain;
    8.         public float infectionGrowthRate;
    9.         public float damage;
    10.         public float range;
    11.         public float rechargeTime;
    12.         public float damageOverTimeValue;
    13.         public int numberOfObjects;
    14.      
    15.     }
    16.  
    17.     private MasterStats masterStats;
    18.  
    19.     public GameStats (PlayerStats playerStats)
    20.     {
    21.         masterStats = new MasterStats();
    22.  
    23.         masterStats.damage = playerStats.damage;
    24.         masterStats.bloodLossRate = playerStats.bloodLossRate;
    25.         masterStats.infectionGrowthRate = playerStats.infectionGrowthRate;
    26.         masterStats.soulGain = playerStats.soulGain;
    27.  
    28.     }
    29.  
    30.     public MasterStats GetStats()
    31.     {
    32.         return masterStats;
    33.     }
    34. }
    35.  
    36. public class GameManager : Monobehavior
    37. {
    38.     //this class is accessable through the Instance
    39.  
    40.     public GameStats currentStats;
    41.  
    42.     //after instantiating the player into the scene
    43.     currentStats = new GameStats(playerReference.GetBaseStats())
    44.  
    45.      public GameStats GetStats()
    46.      {
    47.           return currentStats.GetStats();
    48.      }
    49.  
    50. }
    51.  
    52. public class SomeOtherClass : Monobehavior
    53. {
    54.  
    55.     private void OnCollisionEnter2D(Collision2d other)
    56.     {
    57.         if(other.TryGetComponent(IDamageable))
    58.         {
    59.             IDamageable damageable = other.GetComponent(IDamageable);
    60.             other.TakeDamage(GameManager.Instance.GetStats().damage);
    61.  
    62.             //this line of code above is what I want to accomplish.  I want to store and update
    63.             //all of the various stats for the game in one place and then access them
    64.             //when needed.
    65.         }
    66.     }
    67. }