Search Unity

Skills/Stats

Discussion in 'Scripting' started by Recable, Oct 16, 2017.

  1. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    I'm pretty sure there must be a better more efficient way of doing this, so can anyone tell me what that way is if there is one? Like would an array or list be better than just typing them all out?

    Code (CSharp):
    1. //Skills
    2.     [Header("Health")]
    3.     public int currentHealth; public int maximumHealth; public int healthRegenAmount; public float healthRegenTimer;
    4.     [SerializeField] private bool isRegeningHealth = false; [Space]
    5.  
    6.     [Header("Combat Skills")]
    7.     public int currentMelee; public int totalMelee; [Space]
    8.     public int currentRange; public int totalRange; [Space]
    9.     public int currentMagic; public int totalMagic; [Space]
    10.     public int currentDefence; public int totalDefence; [Space]
    11.     public int currentPrayer; public int totalPrayer;[Space]
    12.     public int currentSlayer; public int totalSlayer; [Space]
    13.  
    14.     [Header("Gathering Skills")]
    15.     public int currentMining; public int totalMining; [Space]
    16.     public int currentFishing; public int totalFishing; [Space]
    17.     public int currentWooductting; public int totalWoodcutting; [Space]
    18.     public int currentHunting; public int totalHunting; [Space]
    19.     public int currentFarming; public int totalFarming; [Space]
    20.     public int currentThieving; public int totalThieving;[Space]
    21.  
    22.     [Header("Production Skills")]
    23.     public int currentCooking; public int totalCooking; [Space]
    24.     public int currentSmithing; public int totalSmithing; [Space]
    25.     public int currentFletching; public int totalFletching; [Space]
    26.     public int currentFiremaking; public int totalFiremaking; [Space]
    27.     public int currentHerblore; public int totalHerblore; [Space]
    28.     public int currentCrafting; public int totalCrafting; [Space]
    29.     public int currentConstruction; public int totalConstruction;
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    You could create a class that holds two values. Current and total. Then create a dictionary to hold whatever instances you need with the key being the name of what it is. "cooking, fishing, etc".

    I suggest dictionary over an array/list as you'd have to have some way to track what those values match to. You could add an enum to your class with the two values that would tell you what it is as well, but the dictionary could handle that for you with the key.

    I would definitely look into making a class out of those. You could even have methods in those classes to do stuff with those values. Like if they level up or maybe have a buff/debuff, etc.
     
    Recable likes this.
  3. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    Hi, thanks for your reply. I'm still quite new to coding so would it be possible to show me examples? I learn better like that, so I can break down the code in my head to learn it. Thanks!
     
  4. TaleOf4Gamers

    TaleOf4Gamers

    Joined:
    Nov 15, 2013
    Posts:
    825
    This is an idea of the implementation that I thought of.
    Code (CSharp):
    1. public class Stats{
    2.     public enum SkillTypes{
    3.         Fishing,
    4.         Mining,
    5.         Melee,
    6.         Ranged
    7.     }
    8.  
    9.     public class Skill{
    10.         public int current;
    11.         public int total;
    12.     }
    13.  
    14.     public Dictionary<SkillTypes,Skill> skills = new Dictionary<SkillTypes,Skill>(){
    15.         { SkillTypes.Fishing, new Skill() },
    16.         { SkillTypes.Mining, new Skill() }
    17.     };
    18. }
    +1 for dictionaries. Definitely a great one to learn.
     
    Recable likes this.
  5. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    Thank you a lot for both your replies! Helped me a lot, got so much to learn.
     
  6. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    Actually, I need some more help about this, how do I access and set the values of my skill levels etc, so far my code looks like this:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public enum SkillTypes {
    6.     //Combat Skills
    7.     Health, Melee, Range, Magic, Defence, Prayer, Slayer,
    8.  
    9.     //Gathering Skills
    10.     Mining, Fishing, Woodcutting, Hunting, Farming, Thieving,
    11.  
    12.     //Production Skills
    13.     Cooking, Smithing, Fletching, Firemaking, Herblore, Crafting, Construction
    14. }
    15.  
    16. public class Skill {
    17.     public int current;
    18.     public int total;
    19. }
    20.  
    21. public class PlayerStats : MonoBehaviour {
    22.  
    23.     public Dictionary<SkillTypes, Skill> skills = new Dictionary<SkillTypes, Skill>() {
    24.         { SkillTypes.Melee, new Skill() },
    25.         { SkillTypes.Range, new Skill() }
    26.     };
    27.  
    28.     public bool gameStarted = false;
    29.  
    30.     //Skills
    31.     //[Header("Health")]
    32.     public int currentHealth; public int maximumHealth; public int healthRegenAmount; public float healthRegenTimer;
    33.     [SerializeField] private bool isRegeningHealth = false;
    34.  
    35.     // Use this for initialization
    36.     void Start() {
    37.         if (!gameStarted) {
    38.             currentHealth = maximumHealth;
    39.             gameStarted = true;
    40.         }
    41.     }
    42.  
    43.     // Update is called once per frame
    44.     void Update() {
    45.         if (currentHealth != maximumHealth && !isRegeningHealth) {
    46.             StartCoroutine(HealthRegen());
    47.         }
    48.     }
    49.  
    50.     IEnumerator HealthRegen() {
    51.         isRegeningHealth = true;
    52.         while (currentHealth < maximumHealth) {
    53.             currentHealth += healthRegenAmount;
    54.             if (currentHealth > maximumHealth) {
    55.                 currentHealth = maximumHealth;
    56.             }
    57.             yield return new WaitForSeconds(healthRegenTimer);
    58.         }
    59.         isRegeningHealth = false;
    60.     }
    61. }
     
  7. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
  8. TaleOf4Gamers

    TaleOf4Gamers

    Joined:
    Nov 15, 2013
    Posts:
    825
    https://www.dotnetperls.com/dictionary
    Just because im not the biggest fan of the MSDN docs ;)
    An example would be:
    Code (CSharp):
    1. // some reference to PlayerStats
    2. PlayerStats playerStats = // Get it somehow
    3.  
    4. playerStats.skills[SkillTypes.Fishing].current += 1;
     
    Recable likes this.
  9. OldRod

    OldRod

    Joined:
    Mar 2, 2009
    Posts:
    136
    This is great. I was just working on this in a project of my own and came here looking for information on using Dictionaries. Thank you!
     
    Recable and TaleOf4Gamers like this.
  10. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    I didn't understand most of this, but then I went around google and just learned so much, then I came back to this still struggling but after a short while of remembering what I've learned and looking through your examples I've finally managed to understand it fully, thanks so much all!
     
  11. TaleOf4Gamers

    TaleOf4Gamers

    Joined:
    Nov 15, 2013
    Posts:
    825
    Its fine. The more you recall it, no matter whether its from memory or googling again, it gets easier every time.
    There so much to learn and no one expects you to remember every nook and cranny of every language.
     
    Recable likes this.
  12. OldRod

    OldRod

    Joined:
    Mar 2, 2009
    Posts:
    136
    And to add to that... nothing is as satisfying as writing your first large chunk of code that actually runs, without having to Google it :)
     
    TaleOf4Gamers and Recable like this.
  13. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    Yeah, I agree with both of you, was quite pleased once I finally got the hang of it. I do have a question though, how would I show my values of the dictionary in my inspector so I can see at runtime what the values are?
     
  14. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    The default inspector doesn't support dictionaries. You'll need a custom inspector.
     
    Recable likes this.
  15. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    As I can't serialize them that means I can't save/load them right? If that's the case how would I do this?
     
  16. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    Should I manually turn them all into ints (is there a way I can use loops to do this) and then save them? Then on load put the int values into the dictionary values?
     
  17. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    So instead of manually setting all their values to 1 (other than health which is 5) like below, is there a way to make all the values start as 1 without typing them all out?

    Code (CSharp):
    1. void StartingStats() {
    2.         skills[SkillTypes.Health].total = 5;
    3.         skills[SkillTypes.Melee].total = 1;
    4.         skills[SkillTypes.Range].total = 1;
    5.     }
     
  18. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Put the default values in the constructor for Skill
    Code (csharp):
    1.  
    2. public Skill()
    3. {
    4.     total = 1;
    5.     current = 1;
    6. }
    7.  
    Or set them on the fields
    Code (csharp):
    1.  
    2. public int Total = 1;
    3.  
     
    TaleOf4Gamers and Recable like this.
  19. Recable

    Recable

    Joined:
    Sep 12, 2017
    Posts:
    61
    *facepalm* thanks...