[SOLVED] How to Tell if PlayerPrefs is Null?

So basically I have a high score and if no high score is found (is null), set high score to equal current score.

I’ve tried using the PlayerPrefs.HasKey function but it doesn’t work at all. The various ways I have tried to use it:

// Method 1 for returning if false
if (!PlayerPrefs.HasKey ("bestTime"))
{
     // Stuff
}

// Method 2 for returning if false
if (PlayerPrefs.HasKey ("bestTime") == false)
{
     // Stuff
}

// Method 3 for returning if false
if (PlayerPrefs.GetString ("bestTime") == null)
{
     // Stuff
}

// Method 1 for returning if true
if (PlayerPrefs.HasKey ("bestTime"))
{
     // Stuff
}

// Method 2 for returning if true
if (PlayerPrefs.HasKey ("bestTime") == true)
{
     // Stuff
}

// Method 3 for returning if true
if (PlayerPrefs.GetString ("bestTime") != null)
{
     // Stuff
}

Every single one of the above don’t return anything.

Any help would be greatly appreciated!

- Chris

2 Likes

PS: I’ve deleted the PlayerPref at start to test things and so I KNOW it returns null, there’s just no function I can find to determine whether it’s null.

just use the default parameter option.

1 Like

when you “get” the value to display on the highscore, if that parameter doesn’t exisist, it will use the default parameter. Which you can set as highscore.

1 Like

Thank you! Didn’t notice the default parameter!

HasKey should work just fine. Odd you’re having issues with it. But good you found a solution that works for you.

In case someone is reading this, I am wondering if the following is the right behaviour:

string str = PlayerPrefs.GetString("key", null);

this seems not to return null as would be expected but more likely a string.default.

so the following would fail:

string str = PlayerPrefs.GetString("key", null);
if(str == null){ }

but instead required:

string str = PlayerPrefs.GetString("key", null);
if(string.IsNullOrEmpty(str) == true){ }
4 Likes

your last code is work for me

I just ran into this problem… wtf Unity? I provided a default value, I want that value back if the key doesn’t exist.

Fair enough, and that is what the API promises, but obviously not what it delivers.

Even as far back as Unity5, supplying a default null to GetString() will give you in fact an empty string if the key in question doesn’t exist.

Before you get too exercised, note that:

a) yes it is annoying because it’s not what the API promises
b) once identified it can be trivially worked around
c) non-null default strings still work precisely as expected
d) Unity is unlikely to change it because it would probably break their own internal stuff
e) this behavior is analogous to a public / serializable string field in a MonoBehaviour/ScriptableObject that you never fill out before serializing. Hint: that won’t be null either, EXCEPT in the case that it is a new never-before-serialized field.

Warts are warts. Show me an API without warts. We know about this wart, as engineers we can deal with it.

2 Likes

I agree with all your points @Kurt-Dekker , it is just annoying to waste time on these undocumented little defects in the API

1 Like

And how do you propose to distinguish if you didn’t pass a second parameter or if you pass null into it? I’m genuinely curious. Because that’s the problem.

1 Like

The methods are separated:

public static string GetString(string key, string defaultValue)
public static string GetString(string key)

There is not a single method defined like this:

public static string GetString(string key, string defaultValue = null)

Actually, they aren’t: https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/PlayerPrefs/PlayerPrefs.bindings.cs

// Returns the value corresponding to /key/ in the preference file if it exists.
        public extern static string GetString(string key, string defaultValue);

        public static string GetString(string key)
        {
            return GetString(key, "");
        }

But this is secondary, the interesting question is the C++ side. Obviously we only can guess, but most likely the string becomes an std:string (which is null-terminated and cannot be null) because of the variable length.
So I think you end up with an empty string with a null-terminator in it. And then in case of the missing key you get back the empty string which becomes an empty managed string after marshalling. And the second definition of the GetString with the empty string second parameter gives the hint in to this direction.
But again, it’s an educated guess since we don’t have the source code for the other side.

2 Likes

Thank You!

Again, please use the “Like” button to show your appreciation rather than necroing threads.

Thanks.