Search Unity

Question Unsure how to make this code repeat

Discussion in 'Scripting' started by PaperMouseGames, Jun 5, 2020.

  1. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    Hi there, I'm working on an RPG with various stats and where each stat levels up based on that stat's XP.

    I'm having issues trying to condense my code though. Here is the block of code I'm having trouble with:

    Code (CSharp):
    1. public void CheckSkillUp()
    2.     {
    3.         if (strengthXP >= strengthXPNeeded)
    4.         {
    5.             strength += 1;
    6.             strengthXP -= strengthXPNeeded;
    7.             strengthXPNeeded = strength * 3;
    8.  
    9.             if (strengthXP >= strengthXPNeeded)
    10.             {
    11.                 CheckSkillUp();
    12.             }
    13.         }
    14.     }
    So the idea is this method gets called when the player earns XP of some sort. Then it checks each stat (in this case strength) and levels them up accordingly. If the user earned enough XP to level up his stat more than once, there's an if statement in there to call the method again.

    Now I only posted the strength stat example here, but I have about a dozen of these stats that level up the exact same way, but with their own XP and XPNeeded variables.

    those variables (in this case, strength, strengthXP, and strengthXPNeeded) are all ints stored in the player class.

    So I'm trying to basically do the above code only once, rather than about a dozen times. I'm sure there's some way to do this but I'm having trouble coming up with a clean solution. Any help would be greatly appreciated!
     
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Seems like they could all be a struct or class which you could just either pass to a method or have a method contained within that deals with it. Hard to say for sure. I'm not following your logic there tbh.
     
  3. MatrixQ

    MatrixQ

    Joined:
    May 16, 2020
    Posts:
    87
    For something like that, you'd usually make a while-loop. It's basically what you do here already, only you've made it recursive.

    But if you've got individual XP for each individual skill, you are probably going to have to write those out for each skill individually.
     
  4. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    @WarmedxMints

    That's actually what I'm experimenting with right now! I should have known, this isn't the first time an issue like this is solved for me by creating a new class. Oh well haha I need to get my mind working that way more, usually I only make classes when I need an entirely new object and not when I need a sort of multidimensional property of an object, but it clearly works great. Thanks for the help!

    @MatrixQ

    That's what I was originally thinking but it was getting messy (I was adding each stat and xp stat to different arrays and iterating through them).

    In the end I think making each stat be made from a class seems to work great. Here is what I came up with in case anyone has a similar issue:

    Code (CSharp):
    1. public class Stat
    2. {
    3.     public int statValue = 0;
    4.     public int xp = 0;
    5.     public int xpNeeded = 0;
    6. }
    So I just threw this class at the bottom of my Player Script and I made an array the size of the number of stats I have and now it works like a charm! The only downside is I have to remember (i.e. write down) which stat is which entry. So strength is element 0 for example and Dexterity is element 1. Not sure of a way around that, but I'm making get methods that are public for each stat so that other classes don't have to know which array element they're looking for.

    It's still a lot of repeated code (the get methods are all mostly the same, just return a different element) but it's a lot less repeated code than I had before.
     
  5. MatrixQ

    MatrixQ

    Joined:
    May 16, 2020
    Posts:
    87
    You can also give that class a string with the name and ask for that instead, so you don't have to rely on the index.
     
  6. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    Hmm I still feel like I'm going to need some method to sort through the passed string and find the appropriate index though right? I could avoid having a dozen different Getters that way, but I'd need a similarly long method to do that sorting.

    Unless I turned the array of Stats into a list and was able to use the Contains method. But I'm not sure you can use that method to find a value inside a list element (i.e. if each Stat has a string name, I'm not sure I can use Contains to find a stat with a particular name within a list of Stats).

    If there is a way to do that, then yeah that'd be the best solution for sure!
     
  7. MatrixQ

    MatrixQ

    Joined:
    May 16, 2020
    Posts:
    87
    Well, once it works, IDs are great, but when you need to, for example, display the skill name or anything, having the skill name listed in the skill object itself would probably be a good idea.
     
  8. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    It's a good point, I ended up expanding the Stat class with a string name, string abbreviation, and adding in an enum for StatType so I can know exactly what to reference when I need to find it from another script.

    So far it's working great! It's easy to send in to a single method the stat I want modified (using the StatType), finding it in the list (with the type), and then manipulating the variables.

    Here is the updated Stat class and so far it's working great!

    Code (CSharp):
    1. public class Stat
    2. {
    3.     public enum StatName { Strength, Dexterity, Endurance, Intelligence, Spirit, Speed, Combat}
    4.  
    5.     public StatName statName;
    6.     public string stringName: "nothing";
    7.     public string stringShort = "nothing";
    8.     public int statValue = 0;
    9.     public int xp = 0;
    10.     public int xpNeeded = 0;
    11. }
    I haven't finished adding in all my stats yet, but the enum system seems to be working well. In the past I've used ScriptableObjects for this, but seeing as how I won't be adding new stats quite as often, it's nice having a single place where they can exist and be accessed.