- Home /
Dynamically building a PlayerPrefs key
Question Update:
Hey all,
I'm writing the code for my savegames using Playerprefs, which only supports integers or floats. I did see that there is a script on the community wiki that adds array support. But because I do not have hundreds of values to save I thought to stay with the supported integers.
So I have about 50 integers named:
Level001, Level002, Etc,
And instead of making huge if statement to set the integers I thought there had to be a way to "dynamically" type them.
So instead of:
If (Loadedlevel == 1)
{
Level001 = 1;
}
someway to combine the beginning of the variable name: Level with the loadedlevel
To get: Level001.
And be able to set that "combined variable" to a value.
I hope this clears up my question, my original question follows:
//// Original question: ////
Hey all,
I'm writing the code for my save games using PlayerPrefs, and as a result I have some integers that I need to set at the end of a level. I've been looking for a way to combine a couple of strings so that I can access my integer variable without a lot of code. something like:
["levelCompletedEasy001_" + theLevelNumber] = 1;
The above doesn't work, but does anyone know of a way to do that properly?
The other way I could think of to solve my problem would be the following, which would result in a lot of lines of code...
function setLevelCompletion(level : int)
{
if (level == 1)
{
levelCompletedEasy001_001 = 1;
}
if (level == 2)
{
levelCompletedEasy002_002 = 1;
}
}
There has to be a more efficient way right?
Thanks a lot!
Answer by CinnaMint · Dec 04, 2011 at 08:49 AM
If you're using PlayerPrefs to save your data, here's what you can do:
PlayerPrefs.SetInt("levelCompletedEasy001_" + theLevelNumber, 1);
The Function works like this: PlayerPrefs.SetInt(STRINGNAME, INTVALUE);. String name of the player prefs, is just a String, period. It's not a variable set in stone. So, you can automate it, by using the + to merge a string, and a number together.
In the above example, PlayerPrefs would see the above like this: PlayerPrefs.SetInt("levelCompletedEasy001_7", 1); basically.
This can be also done inside a FOR loop, for example, to set ALL of your levels to INT 1, like this:
for (int i = 0; i < maxNumberOfLevels; i++)
{
PlayerPrefs.SetInt("levelCompletedEasy001_" + i, 1);
}
Of course, saving just the current level to the PlayerPrefs after the stage is complete wouldn't need a huge for/loop like that. It'd be better used for loading data for scores and stuff when the game starts.
Edit: Here's your above example, written out as what I mentioned:
function setLevelCompletion(level : int)
{
PlayerPrefs.SetInt("levelCompletedEasy001_" + level, 1);
}
Spiced up:
function setLevelCompletion(difficulty : String, level : int)
{
PlayerPrefs.SetInt("levelCompleted" + difficulty + "001_" + level, 1);
}
Wow, thanks! I feel so stupid for having al those seperate integers now. I was doing everything double.. Cheers!
Don't feel stupid. :) It's common for something so simple to ellude people. It happens to me all the time. I'm glad it worked for you! Good luck with the rest of your coding!
Thanks, Thanks a lot. this solution gives me released from hundred line of code and also from if else if, ..... Again thanks
Answer by jahroy · Dec 03, 2011 at 07:33 PM
Here is how you would add an int to the end of a string:
var someString : String = "I am string number " + 4;
Debug.Log("Result: " + someString);
/ the following will be printed to the console: Result: I am string number 4 */
Another example:
var stringPrefix : String = "Level number ";
for ( var i = 0; i < 10; i ++ ) {
var freshString : String = stringPrefix + i;
Debug.Log("Here is the string ---> " + freshString);
}
Or... The real way to do it with a function:
function getLevelLabel ( inputNumber : int ) : String { var thePrefix : String = "Level number ";
return thePrefix + inputNumber;
}
Hey, thx for the answer!
I'm not sure how this enabels me to set the integer named in the string. Your code just allows me to combine strings right? I want to set a dynamically typed variable: So for instance i have an integer:
Var level1 : int = 0; (0 defining the level as uncompleted)
And i want to set it by doing something like:
Var levelToSet : int = 1;
("level" + levelToSet )= 1;
Thanks!
Hey, thanks again for the answer! I'm sorry that I've been unclear. To outline the situation: Playerprefs does not support arrays, and because I do not have hundreds of levels. I thought to stay with the supported int's and not use the script from the wiki that adds the support.
So what i do have is around 50 integers named: level001, level002 etc.
And ins$$anonymous$$d of a huge if statement that checks the level and sets the ints accordingly, i thought there had to be a way to "dynamically type "those integer names and access them that way.
Actually, while I was typing all that junk I think somebody else came up with a better (more simple) answer. Talk about a bunch of people over-complicating something simple!!
Hey, Cinna$$anonymous$$ts answer indeed solves my problem, and i feel stupid for not seeing it mysef... I don't know how to describe what i was trying to do any other way though. and not trying to be secretive at all :) i guess the problem is me trying to ask a question in a language that I'm not fluent in :/ thanks again for all the support!
Understood.
I'm glad we were able to find your solution and am impressed by anybody who speaks multiple languages (especially to discuss such complex stuff)!
I recommend changing the title of your question to something like this:
"Dynamically building a PlayerPrefs key"
or
"Storing Level Scores to PlayerPrefs"
That way more people will find it (and hopefully find it helpful).
I guess the problem is it's hard to describe certain problems when you don't know the ter$$anonymous$$ology until after the question is answered!
Answer by gfr · Dec 03, 2011 at 10:49 PM
That's what containers like arrays and dictionaries are used for, e.g. something like:
private var levelCompletion : Array;
function Start() {
levelCompletion = new Array(levelCount);
// initialize from preferences...
}
function setLevelCompletion(level : int) {
levelCompletion[level] = true;
}
I don't see the need for strings for access here, but in cases where you definitely need that take a look at dictionaries or hash tables (e.g. explained here).
Hey thanks your answer! That link looks like a great resource! But I'm trying to save to the player prefs which does not support array's or hash tables or dictionary's. I thought to stay within the supported integers and thought there had to be a way of "dynamically typing" a variable in order ro set it. I will change my question accordingly.
Answer by jahroy · Dec 04, 2011 at 08:53 AM
I think I've finally figured out what you're trying to do.
Below is an example that writes a string to the PlayerPrefs that represents a players score on each level of a game.
It's actually just a couple functions (one that creates the string, one that reads it).
It works like this:
There is an array named levelScores which keeps track of the user's score on each level.
The function buildSaveScoresString iterates over the array of scores and returns a string that looks like this:
0=2000|1=4500|2=5555|3=2456|4=99999|5=87298|
I'm using what we call the pipe symbol to separate the score for each level. I'm using an equal sign to separate the level number from the score.
This string can be written to the PlayerPrefs and processed later by the function named processSaveScoresString.
The function named processSaveScoresString uses the String.Split() function to parse the contents of the string and print some info to the console.
All of this code is 100% untested... It's just meant to give you an idea of how to do it yourself.
Hope it helps!
/* array of scores for each level */
var levelScores : int [];
/* build a string with score data for each level */
function buildSaveScoresString () : String
{
var saveString : String = "";
for ( var i : int = 0; i < levelScores.length; i ++ ) {
var thisScore : int = levelScores[i];
saveString += "" + i + "=" + thisScore;
/* use the pipe symbol to separate levels */
saveString += "|";
}
return saveString;
}
function parseSaveScoresString ( inputString : String ) : void
{
if ( ! inputString ) {
Debug.LogWarning("Input string is null");
return;
}
/* split the string by the pipe symbol */
var theLevels : String [] = inputString.Split("|"[0]);
for ( var thisLevel : String in theLevels ) {
/* split each string by the equal sign */
var theSplit : String [] = thisLevel.Split("="[0]);
if ( ! theSplit || theSplit.length < 2 ) {
Debug.LogWarning("parse error: " + thisLevel);
continue;
}
var theLevel : String = theSplit[0];
var theScore : String = theSplit[1];
Debug.Log("Score for level " + theLevel + ": " + theScore);
}
}
Cinna$$anonymous$$int's answer is better than $$anonymous$$e.
There is no reason to do all the stuff my code is doing.
PlayerPrefs works just like a hashtable or a dictionary, so you can use it to directly store name/value pairs.
As far as I can tell, that's what you're trying to do.
Your answer
Follow this Question
Related Questions
PlayerPrefs for saving strings 1 Answer
PlayerPrefs script problem 2 Answers
How to convert raw keycode to characters 1 Answer
PlayerPrefs from One App to Another. 1 Answer
PlayerPrefs Question 0 Answers