For my game I use PlayerPrefs to store the overall player score and the score for every level. In editor, there were no issue with creating, updating and deleting PlayerPrefs. But when I build the game, issues started to show up.
The PlayerPrefs would be created and updated as usual, but the deletion was broken.
This is the code that is used in a button to reset the score
public void ResetProgress()
{
foreach (string file in Directory.GetFiles(Application.persistentDataPath))
{
File.Delete(file);
}
PlayerPrefs.DeleteAll();
PlayerPrefs.Save();
}
In editor, this button will delete the PlayerPrefs from the registry(I used regedit and an addon from the asset store to make sure of that). But when build, the registries will simply stay and the scene that shows the values provided by those PlayerPrefs will not change.
This is the code for saving data
string path = Application.persistentDataPath "/" levelName ".dat";
//Check if there is any save file to begin with
if(File.Exists(path))
{
File.AppendAllText(path, playerSolution Environment.NewLine);
string[] playerValues = PlayerPrefs.GetString(SceneManager.GetActiveScene().name).Split('-').ToArray();
PlayerPrefs.SetString(SceneManager.GetActiveScene().name, $"{int.Parse(playerValues[0]) 1}-{playerTime}");
}
else
{
File.WriteAllText(path, playerSolution Environment.NewLine);
PlayerPrefs.SetString(SceneManager.GetActiveScene().name, $"1-{playerTime}");
}
if(PlayerPrefs.HasKey("AllPlayerScore"))
{
PlayerPrefs.SetInt("AllPlayerScore", PlayerPrefs.GetInt("AllPlayerScore") 1);
}
else
{
PlayerPrefs.SetInt("AllPlayerScore", 1);
}
PlayerPrefs.Save();
And yes, I am aware that when you build a game, the registry directory will change. I've also tried to delete the registries to see if somehow my values are being cached, but no. Everything resets as expected.
Some final notes:
- The files that I create and delete are not connected to scores
- The logic from the button IS being called, because the files are being deleted
- The project is build in LTS version 2020.3.30f1
UPDATE 1: I have no clue why, but the problem was fixed in the button logic when I moved the PlayerPrefs.DeleteAll() to be executed before the file removal. I will keep the post open, so that someone far more knowledgeable can explain the issue.
CodePudding user response:
This might be a hunch, but I would like you to be aware of the following, which is to long for a comment:
The path separation character differs between Windows \
and Unix /
like systems. This might lead to incorrect paths when you do cross-platform development and hence, failing to load data.
To overcome this you should use Path.PathSeparator
or Path.
static functions whenever possible.
So:
string path = Application.persistentDataPath "/" levelName ".dat";
would become:
string path = Application.persistentDataPath
Path.PathSeparator levelName ".dat";
Do note you might have the same issue with the Application.persistentDataPath
variable.
See: https://docs.microsoft.com/en-us/dotnet/api/system.io.path.pathseparator?view=net-6.0
CodePudding user response:
I'm going to call this a partial answer. In some cases when I reproduce this problem, the method is exiting early due to an exception caused by a file refusing to be deleted which skips the PlayerPrefs.DeleteAll(); PlayerPrefs.Save();
calls.
Surrounding the call in a try/catch block fixes this particular cause.
public void ResetProgress()
{
foreach (string file in Directory.GetFiles(Application.persistentDataPath))
{
try
{
File.Delete(file);
}
catch {}
}
PlayerPrefs.DeleteAll();
PlayerPrefs.Save();
}