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!

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);
}

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;
}

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).

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*;*
  •  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);*
    
  • }*
    }