In my game you can buy stuff through menu. Each thing has a PlayerPrefs key so it’s state could be saved (if it’s bought or if it’s still not) I got an array of 12 crosshair states, the idea is that if the array object coresponding to the right crosshair is 1, than the crosshair has been bought, but if it’s 0, than it’s not. I’m using 1 and 0, cuz PlayerPrefs can’t save boolean.
So I have this in the Start function to get the saved crosshair states and put them into the array:
if(PlayerPrefs.HasKey("c0")){ //we only need to check one crosshair's state to see if there's a save
for(i=0; i < crosshairPurchases.length; i++){//if there's a save, then get all crosshairs from PlayerPrefs
crosshairPurchases[i]= PlayerPrefs.GetInt("c" + i);
print(crosshairPurchases[i]);}
}
else{
//Otherwise, if we're running the game for the first time
// than only unlock the first crosshair
// the player will have to buy the others
crosshairPurchases[0]= 1;
for(i=1; i < crosshairPurchases.length; i++){
crosshairPurchases[i] = 0;
print(crosshairPurchases[i]);
}
}
The problem is that print doesn’t output anything and if I use a member of the array in the script below the console says ArgumentOutOfRangeException. I can do it line by line, asigning member by member, but the script gets huge and this is really not a good idea. But why does this not work?
How do you initialize your crosshairPurchases array? I’m betting you initialize it without any length (so it’s length 0 and never goes into your loop)
And looking at line 22 in PlayerPrefsX, if the user passes an empty array (which, in my opinion, is still a valid value) will cause an IndexOutOfRange exception. (same with the other array saves)
EDIT: I see you posted at the same time as me, let me review it
You assign the GetIntArray return to an element of your array, not to the array itself.
Eric, if you slightly alter your PlayerPrefsX instead like so:
var sb = new System.Text.StringBuilder();
if (floatArray.Length > 0)
{
for (i = 0; i < floatArray.Length-1; i++) {
sb.Append(floatArray[i]).Append("|");
}
sb.Append(floatArray[i]);
}
I think the rest of the logic, including the various Get____Array methods, will work out for your extension to be compatible with empty arrays.
EDIT: no wait, you’d have to do a check in the Get methods if the saved string was empty or not, otherwise it will attempt to create a length 1 array and parseFloat/Int an empty string. Same for the string array, it’d return a length 1 array with its element being an empty string – of which you wouldn’t be able to discern the difference between the user saving an empty string array or a string array with 1 element that’s an empty/null string.
So unless you tweak your serialization process, it might be a pain.
Yeah, I think it’s better to do what I did and return false if trying to save an empty array, because if that ever happened it would pretty much have to be a coding error (I can’t imagine actually wanting to try saving an empty array).
In my experience, empty arrays are often perfectly valid. Although, most of my experience has been in developing general use APIs, dynamic software, user driven logic which seems to not be the case with Unity.