Hi Mark -
I don’t think there’s a straightforward way to accomplish what you’re looking for with PlayerPrefs as it’s not really designed for storing complex data (it should normally be used only for saving user-specific options plus, occasionally, installation-specific stuff, such as whether the user has seen a particular screen before).
Assuming you’re willing to look into more comprehensive saving solutions (such as saving the data as JSON), I’d approach it somewhat like this:
- Create a Gem class with a public int for an ID and a public bool for whether the gem has been collected before or not. When adding a gem while designing a level, you’ll just need to manually add an id to that gem (e.g., 0, 1, 2, 3, etc).
- Create a Level class that stores level-specific information, such as high scores, status of gems (collected or not), etc.
- Ideally, you would create a List gems which will get populated upon instantiation (see below)
- Upon instantiating the level, have each gem add itself to the list of gems using its ID (e.g., gems.Insert(id,this)). Upon adding the gem, have it check for whether it’s been collected before - if it’s been collected before, have it immediately run gameobject.SetActive(false). This way, you’re only left with gems that haven’t been collected before - those that have been will have disabled themselves.
- Add a event or a method for tracking gem collect events - the idea is that when the gem is collected, its corresponding bool changes to true.
- Now, the reason we add them all to the list is that we will need some way to persist this data - and, using this approach, you can save the status of each level when you save the game - simply loop through the list of levels to save the status of each level - including the status of each gem.
These are just broad strokes, of course - depending on your case, you could further optimize the code by only saving those levels that have changed and only loading the level/gem that’s about to be played.
But, essentially, the broad outline is to a) create classes that store the data you need; b) arrange these classes into a list for easy saving/loading; and c) loop through the list to save/load game data as required.
P.S. Writing JSON saves is pretty easy - here’s an example from my project. First, create the class you will use to store save data - think of it as a “template” for your save game:
[Serializable]
public class Save {
public List<Level> savedLevels = new List<Level>();
}
When you’re reading to start saving, create an instance of the Save class and loop through your list of levels to store them:
void SaveLevelsToFile()
{
save.savedLevels.Clear();
for (int i = 0; i < levels.Count; i++)
{
data.savedLevels.Add(levels[i]);
}
}
And, finally, write the contents of the Save class to system storage using JSON serialization:
string jsonData = JsonUtility.ToJson(save, true);
File.WriteAllText(Application.persistentDataPath + "/playerSave.json", jsonData);
Good luck,
George