Help with deleting a binary / Spawn with default values

Hi!

So I’ve managed to make a Binary save system from Brackeys youtube video, I have it so that it saves my players position and number of hearts.

public static void SavePlayer (PlayerStats player)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        string path = Application.persistentDataPath + "/player.dat";
        FileStream stream = new FileStream(path, FileMode.Create);

        PlayerData data = new PlayerData(player);

    

        formatter.Serialize(stream, data);
        stream.Close();
    }

public static int[] LoadPlayer()
    {
        if (File.Exists(Application.persistentDataPath + "/player.dat"))
        {
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream stream = new FileStream(Application.persistentDataPath + "/player.dat", FileMode.Open);
 
            PlayerData data = formatter.Deserialize(stream) as PlayerData;

            stream.Close();
            return data.stats;
        }
        else
        {
            Debug.LogError("File does not exist.");
            return new int[4];
        }
    }

[System.Serializable]
    public class PlayerData
    {
        public int[] stats;
        public float[] position;

        public PlayerData(PlayerStats player)
        {
            stats = new int[4];
            stats[0] = player.level;
            stats[1] = player.numOfHearts;
            stats[2] = player.attack;
            stats[3] = player.defence;

            position = new float[3];
            position[0] = player.transform.position.x;
            position[1] = player.transform.position.y;
            position[2] = player.transform.position.z;
        }
    }

I then found a solution through some searching, how to delete the saved file, like a Clear Save in the main menu…

public static int[] DeletePlayerStats()
    {
     string path = Application.persistentDataPath + "/player.dat";
        if (File.Exists(path))
       {
            File.Delete(path);

            return null;
        }
        else
        {
           return null;
        }
        }

The problem with this and I don’t know if I’ve made any errors… Is that the saved file gets deleted which I’m happy about, but my player doesn’t spawn with my default values.(Not even sure if ive set any default values, if so where?) I want the player to spawn back to the beginning of my game, and spawn with 3 hearts. In the PlayerStats script, it even says "public int numOfHearts = 3; and I tried setting it in the Start method aswell, but that would just make my player always spawn with 3 hearts, even if I got 4 and saved.

I can’t figure this out, and I’ve tried alot of ways but it always ends up with my player spawning with 0 hearts and plays the death animation. (Im a beginner so might be an easy solution that i cant solve)

I tried writing return new int[4]; instead of return null; in DeletePlayerStats, but that also doesn’t work, at this point I don’t even know what I’m doing.

Can’t you just set the default values when you try to Load and no file is found?

Hm… It says return new int[4]; on LoadPlayer, and in DeletePlayerStats I tried the same, I’m not really sure what to do here to be honest, this binary thing is new to me but I feel like I am just missing something very little, I just somehow need to know where and how to set my hearts and position to be a value only when a file is deleted :confused:

Do I perhaps need to set something else inside the PlayerStats script? I do have a public int numOfHearts = 3; there already so that shouldn’t be the problem

So, what I’m trying to hint at, is instead of returning a blank array upon failing to load the Player’s data, just return your default values. That way, when the game reloads and you spawn, it will check for the Player’s data, see it’s not there, and then use your default values.

Don’t use the binary formatter/serializer: it is insecure, it cannot be made secure, and it makes debugging very difficult, plus it actually will NOT prevent people from modifying your save data on their computers.

Do consider switching to something like JSON , which is much safer as well as easier to work with when debugging.

Load/Save steps:

When loading, you can never re-create a MonoBehaviour or ScriptableObject instance directly from JSON. The reason is they are hybrid C# and native engine objects, and when the JSON package calls new to make one, it cannot make the native engine portion of the object.

Instead you must first create the MonoBehaviour using AddComponent() on a GameObject instance, or use ScriptableObject.CreateInstance() to make your SO, then use the appropriate JSON “populate object” call to fill in its public fields.

If you want to use PlayerPrefs to save your game, it’s always better to use a JSON-based wrapper such as this one I forked from a fellow named Brett M Johnson on github:

If you selected binary to “protect your data,” keep this in mind:

If you’re concerned about the user ‘hacking your save files,’ or ‘cheating in your game,’ just don’t be. There’s nothing you can do about it. Nothing is secure, it is not your computer, it is the user’s computer. If it must be secure, store it on your own server and have the user connect to download it.

Anything else is a waste of your time and the only person you’re going to inconvenience is yourself when you’re debugging the game and you have savegame errors. Work on your game instead.

Remember, it only takes one 12-year-old in Finland to write a script to read/write your game files and everybody else can now use that script. Read about Cheat Engine to see more ways you cannot possibly control this.

The good news is that most likely nobody will care enough about your game to bother, so you’re safe.