Automatically loading multiple different files with binary formatting.

Hey all, I’ve been working on this portion of my project for a couple weeks now. I’ve learned a lot, but can’t quite pin down the correct method. In the upcoming code, I have what’s called a stat block. This is a script attached to an object that is instantiated whenever a user saves a game that they are trying. The stat block is the script that is there to hold the information. There is a stat block for multiple sports (the one in the example is cheer). I have it to where I can create stat blocks, as well as tap them to reopen the appropriate screen to edit them (the values all get reset to 0 after an update, but that’s for another time). The issue I’m having is making sure that the stat blocks are saved, and loaded, even if the application is closed. From what I gathered, there isn’t a straight forward way to do this, and the closest I could come was binary serialization. I have watched the unity tutorial, and have been following that. The biggest difference is that I am going to have to have multiple saves being loaded simultaneously? I’m not sure exactly the best way to do it. However, with what I have, it’s having issues with not having appropriate football information, and also can’t find the appropriate file path. If anyone knows of a way to save and load multiple game objects with scripts, or can figure out what I’m doing and how to fix it, that would be awesome. Here is the code for the cheer stat block:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;

public class StatBlockCheer : MonoBehaviour {
    public TMP_Text playerName;
    public TMP_Text gameName;
    public TMP_Text playerNumber;
    public TMP_Text date;
    public RectTransform sprite;

    public string timer;

    public string tumbleLand;
    public string tumbleMiss;
    public string stuntLand;
    public string stuntMiss;

    public void Awake()
    {
        AutoLoad();
        Debug.Log(Application.persistentDataPath);
    }

    public void SetTime(string timerInput)
    {
        timer = timerInput.ToString();
    }
    public void SetPlayerName(string playerNameInput)
    {
        playerName.text = playerNameInput;
    }
    public void SetGameName(string gameNameInput)
    {
        gameName.text = gameNameInput;
    }
    public void SetPlayerNumber(string playerNumberInput)
    {
        playerNumber.text = playerNumberInput;
    }
    public void SetDate(string dateInput)
    {
        date.text = dateInput;
    }
    public void SetSprite(RectTransform imageInput)
    {
        sprite.GetComponent<RawImage>().texture = imageInput.GetComponent<RawImage>().texture;
    }public void SetTumbleLand(string tumbleLandInput)
    {
        tumbleLand = tumbleLandInput;
    }
    public void SetTumbleMiss(string tumbleMissInput)
    {
        tumbleMiss = tumbleMissInput;
    }
    public void SetStuntLand(string stuntLandInput)
    {
        stuntLand = stuntLandInput;
    }
    public void SetStuntMiss(string stuntMissInput)
    {
        stuntMiss = stuntMissInput;
    }
    public void SaveCheer()
    {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Create(Application.persistentDataPath + "/StatBlocks/" + date.text + gameName.text + "CheerGame.save");

        CheerStats data = new CheerStats();
        data.playerName = playerName.text;
        data.playerNumber = playerNumber.text;
        data.gameName = gameName.text;
        data.date = date.text;
        data.spriteName = sprite.GetComponent<RawImage>().texture.name;
        data.tumbleLand = int.Parse(tumbleLand);
        data.tumbleLand = int.Parse(tumbleMiss);
        data.stuntLand = int.Parse(stuntLand);
        data.stuntMiss = int.Parse(stuntMiss);

        bf.Serialize(file, data);
        file.Close();
    }
    public void AutoLoad()
    {
        BinaryFormatter bf = new BinaryFormatter();
        DirectoryInfo dir = new DirectoryInfo(Application.persistentDataPath);
        FileInfo[] saves = dir.GetFiles("*.*");
        foreach (FileInfo f in saves)
        {
            FileStream file = File.Open(f.ToString(), FileMode.Open);
            CheerStats data = (CheerStats)bf.Deserialize(file);
            if(data.spriteName == "cheer")
            {
                timer = data.timer.ToString();
                tumbleLand = data.tumbleLand.ToString();
                tumbleMiss = data.tumbleMiss.ToString();
                stuntLand = data.stuntLand.ToString();
                stuntMiss = data.stuntMiss.ToString();
                playerName.text = data.playerName;
                playerNumber.text = data.playerNumber;
                gameName.text = data.gameName;
                date.text = data.date;
                sprite = Resources.Load(data.spriteName) as RectTransform;
            }
            file.Close();
        }
    }
    public void OnApplicationQuit()
    {
        SaveCheer();
    }


}
[Serializable]
public class CheerStats
{
    public int timer;
    public string playerName;
    public string playerNumber;
    public string gameName;
    public string date;
    public string spriteName;
    public int tumbleLand;
    public int tumbleMiss;
    public int stuntLand;
    public int stuntMiss;
}

Binary serialization is probably one of the most finnicky and difficult ways of dealing with this problem. I do not recommend this approach.

Instead use a text-readable serialization format such as JSON. It will be far simpler and the serialized data is still human readable so you can find your bugs and fix them in a reasonable amount of time.

Now if you’re just looking to make preconfigured blobs of data that won’t change after you build the game, I would highly recommend using instead the Unity built-in ScriptableObject class. There are tons of tutorials on those.

Thanks for the quick reply. I can see the JSON usage. I didn’t know that was as easy as it seems. I’m not entirely sure how to save that to a file and load multiple copies, but I’m sure I can figure it out. I would like to know how scriptable objects could help me in this instance though.