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): //Skills [Header("Health")] public int currentHealth; public int maximumHealth; public int healthRegenAmount; public float healthRegenTimer; [SerializeField] private bool isRegeningHealth = false; [Space] [Header("Combat Skills")] public int currentMelee; public int totalMelee; [Space] public int currentRange; public int totalRange; [Space] public int currentMagic; public int totalMagic; [Space] public int currentDefence; public int totalDefence; [Space] public int currentPrayer; public int totalPrayer;[Space] public int currentSlayer; public int totalSlayer; [Space] [Header("Gathering Skills")] public int currentMining; public int totalMining; [Space] public int currentFishing; public int totalFishing; [Space] public int currentWooductting; public int totalWoodcutting; [Space] public int currentHunting; public int totalHunting; [Space] public int currentFarming; public int totalFarming; [Space] public int currentThieving; public int totalThieving;[Space] [Header("Production Skills")] public int currentCooking; public int totalCooking; [Space] public int currentSmithing; public int totalSmithing; [Space] public int currentFletching; public int totalFletching; [Space] public int currentFiremaking; public int totalFiremaking; [Space] public int currentHerblore; public int totalHerblore; [Space] public int currentCrafting; public int totalCrafting; [Space] public int currentConstruction; public int totalConstruction;
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.
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!
This is an idea of the implementation that I thought of. Code (CSharp): public class Stats{ public enum SkillTypes{ Fishing, Mining, Melee, Ranged } public class Skill{ public int current; public int total; } public Dictionary<SkillTypes,Skill> skills = new Dictionary<SkillTypes,Skill>(){ { SkillTypes.Fishing, new Skill() }, { SkillTypes.Mining, new Skill() } }; } +1 for dictionaries. Definitely a great one to learn.
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): using System.Collections; using System.Collections.Generic; using UnityEngine; public enum SkillTypes { //Combat Skills Health, Melee, Range, Magic, Defence, Prayer, Slayer, //Gathering Skills Mining, Fishing, Woodcutting, Hunting, Farming, Thieving, //Production Skills Cooking, Smithing, Fletching, Firemaking, Herblore, Crafting, Construction } public class Skill { public int current; public int total; } public class PlayerStats : MonoBehaviour { public Dictionary<SkillTypes, Skill> skills = new Dictionary<SkillTypes, Skill>() { { SkillTypes.Melee, new Skill() }, { SkillTypes.Range, new Skill() } }; public bool gameStarted = false; //Skills //[Header("Health")] public int currentHealth; public int maximumHealth; public int healthRegenAmount; public float healthRegenTimer; [SerializeField] private bool isRegeningHealth = false; // Use this for initialization void Start() { if (!gameStarted) { currentHealth = maximumHealth; gameStarted = true; } } // Update is called once per frame void Update() { if (currentHealth != maximumHealth && !isRegeningHealth) { StartCoroutine(HealthRegen()); } } IEnumerator HealthRegen() { isRegeningHealth = true; while (currentHealth < maximumHealth) { currentHealth += healthRegenAmount; if (currentHealth > maximumHealth) { currentHealth = maximumHealth; } yield return new WaitForSeconds(healthRegenTimer); } isRegeningHealth = false; } }
https://msdn.microsoft.com/en-us/library/bb347013(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/kw5aaea4(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/9tee9ht2(v=vs.110).aspx
https://www.dotnetperls.com/dictionary Just because im not the biggest fan of the MSDN docs An example would be: Code (CSharp): // some reference to PlayerStats PlayerStats playerStats = // Get it somehow playerStats.skills[SkillTypes.Fishing].current += 1;
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!
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!
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.
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
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?
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?
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?
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): void StartingStats() { skills[SkillTypes.Health].total = 5; skills[SkillTypes.Melee].total = 1; skills[SkillTypes.Range].total = 1; }
Put the default values in the constructor for Skill Code (csharp): public Skill() { total = 1; current = 1; } Or set them on the fields Code (csharp): public int Total = 1;