How to optimize a long list through code

Hello, I’m currently trying to create some achievements but I don’t really know how to optimize this.

As you can see below I currently have 55 achievements but is pretty annoying to do it through the inspector, I’d like to set name, description, ID, goal, reward amount through code to edit it on the fly.


This is the Achievement class inside my AchievementManager

[System.Serializable]
    public class Achievement
    {
        //Base achievement
        public Sprite icon;
        public string name;
        public string description;

        //Achievement Stuff
        public string ID;
        public double current;
        public double goal;
        public bool isCompleted;
        public bool isClaimed;
        public bool isHidden;

        //Reward
        public Sprite rewardIcon;
        public double rewardAmount;
        public RewardType rewardType;
    }
    #endregion

I’m using a “Dictionary” script (Bad name and look I know) to save the achievements name

I was wondering if something like converting the names into a single string array and then using a loop to go through the achievements names to set the name of them like:

for (int i =0; i< stringArray.Lenght; i++) {

achievement.name = stringArray[i];
}

and if I can do the same with description, ID, goal, reward amount. I don’t mind to set 55 or 200 images because is faster than this.

Sounds like you have a handle on it; what is the problem?

1 Like

Like I said I have to fill this class below for every achievement I want to add, the icon and reward is not a big deal but descriptions, names, and IDs yes so I wanted to optimize this part and I don’t like the way I’m doing now because if I want to add an achievement under a “category” I have to redo everything (I like to be organized and put every achievement of the same category together then the other category and so on).

[System.Serializable]
    public class Achievement
    {
        //Base achievement
        public Sprite icon;
        public string name;
        public string description;
        //Achievement Stuff
        public string ID;
        public double current;
        public double goal;
        public bool isCompleted;
        public bool isClaimed;
        public bool isHidden;
        //Reward
        public Sprite rewardIcon;
        public double rewardAmount;
        public RewardType rewardType;
    }

All of that data can be stored as a string if you wish. Any specific issues you are having?

1 Like

I posted a picture of my Dictionary script (bad script name and if you like your like please don’t look at it), I convert the IDs to a string[ ] but I have to give to every achievement a name before populating the canvas (which is done when pressing on a button) but I’m unsure on how to do this

Multidimensional arrays is a fine way to do it.

    string[,] categorizedDataAsString = new string[3, 3] 
    {
    { "", "Name0", "ID0" },
    { "", "Name1", "ID1" },
    { "", "Name2", "ID2" }
    };
        Debug.Log(categorizedDataAsString[0, 1]); //name
        Debug.Log(categorizedDataAsString[0, 2]); //id
        Debug.Log(categorizedDataAsString[1, 1]); //name
        Debug.Log(categorizedDataAsString[1, 2]); //id
        Debug.Log(categorizedDataAsString[2, 1]); //name
        Debug.Log(categorizedDataAsString[2, 2]); //id
1 Like

After some test, I’ve got this and it works as intended, I have to replace the 4 with the number of values inside the array

for (int i = 0; i < 4; i++)
        {
            achievements[i].name = Dictionary.Instance.achievementIDs[i, 0];
            achievements[i].description = Dictionary.Instance.achievementIDs[0, 1];
            achievements[i].ID = Dictionary.Instance.achievementIDs[i, 2];
            achievements[i].goal = int.Parse (Dictionary.Instance.achievementIDs[i, 3]);
            achievements[i].rewardAmount = int.Parse (Dictionary.Instance.achievementIDs[i, 4]);
        }

Edit:
can string[,] categorizedDataAsString = new string[4, 3] the first 3 be set through inspector? it wants a constant variable

Edit 2:
Now with the list I don’t know how to call specific IDs to add progress

public void AddAchievementProgress (string ID, double value)
    {
        Achievement achievement = achievements.FirstOrDefault (x => x.ID == ID);
        if (achievement.isHidden) return;
        if (!achievement.isCompleted)
        {
            achievement.current += value;

            if (achievement.current >= achievement.goal)
            {
                achievement.current = achievement.goal;
                achievement.isCompleted = true;
                ShowUnlockNotification (achievement);
            }
            GameController.Instance.saveSystem.LoadAchievements (GameController.Instance.AchievementsFile ());
            SaveAchievementsProgress (achievement.ID);
        }
    }

How can I call the achievement with ID “ACH_I_WANT_THIS” from that list? I need to call multiple of the at the same time so I need something like:

string CLICK_ME = "ACH_CLICK_ME_10_TIMES";

or better:

string[] CLICK_ME = {"ACH_CLICK_ME_10_TIMES", "ACH_CLICK_ME_30_TIMES", "ACH_CLICK_ME_60_TIMES"};
for(x = 0; x < 4; x++)
{
    for(y = 0; y < 4; y++)
    {
        if(y==2) //id
        {
            if(categorizedDataAsString[x,y] == "ACH_CLICK_ME_10_TIMES")
            {
                 //desired id
            }
        }
    }
}

Thanks but I realized I’m a complete dumb, I can just call

 AchievementsManager.Instance.AddAchievementProgress (ACHIEVEMENT_NAME, amount);

to add progress to achievement. Now I need to optimize the achievement scroll view because it lags when I open it (since it loads ~70 achievements even if not visible), if you have a suggestion please let me know! I prefer a solution made using code and not pre-made by someone