How to store multiple variable type in one "list" to save and load them easily ?

Hello,
Since i’m a beginner in C# i got some issue with the way to do thing, even if i completely got the logic^^.

I’m building a game like a “Heroe Clicker / Tap Titan”, which is perfecltly working so far, but i am facing a wall to easily save all my variables and get them without writing dozens of lines for each.

My player class is currently something like this :

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[System.Serializable]

public class Player{
    public static Player current;
    public static float Life = 500;
    public static float LifeLvl = 1;
    public static float LifeAdd = 50;
    public static float afk_death_timer = 2;
    public static float Strengh = 60;
    public static float StrenghLvl = 1;
    public static float StrenghAdd = 15;
.... bool
...int
.... string
.... douzens of other stats

(Its all static because i’m not gonna have other Characters so i don’t see the point to instantiate this multiple times, maybe i’m wrong ?)
Plus other game variables in another class such as the time played, UI buttons and Perks activated ingame before saving…

But currently to save them i have to manually add them one by one in Playerprefs and get them One by one in the Loading function. Which make each of this fonction close to 200 code lines.

I though i can put them in a List like this : Player List[string name, string type, string value]
(Life,int,500), (LiveActivation, bool, true)

And then save and get Player[ ] in one line on the save and load function ?
But then i will have to convert each one according to its type i’m not sure how.

something like this ? : Life = Player[Life].value.ToInt if if type is Int, .ToFloat if type is float… ?

I also hearded about a method to save a complete Class from serialization, so i tried this :

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

public static class SaveLoad {

    public static List<Player> savedGames = new List<Player>();

    //it's static so we can call it from anywhere
    public static void Save() {
        SaveLoad.savedGames.Add(Player.current);
        BinaryFormatter bf = new BinaryFormatter();
        //Application.persistentDataPath is a string, so if you wanted you can put that into debug.log if you want to know where save games are located
        FileStream file = File.Create (Application.persistentDataPath + "/savedGames.gd"); //you can call it anything you want
        bf.Serialize(file, SaveLoad.savedGames);
        file.Close();
        Debug.Log (Application.persistentDataPath);
        Debug.Log (savedGames);

    }

    public static void Load() {
        if(File.Exists(Application.persistentDataPath + "/savedGames.gd")) {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.persistentDataPath + "/savedGames.gd", FileMode.Open);
            SaveLoad.savedGames = (List<Player>)bf.Deserialize(file);
            file.Close();
            Debug.Log (savedGames);
        }
    }
}

But the result was an almost empty file in the save folder, with just th ename of the class apparently saved…

I would really appreciate if someone can show me an easy way for this.
Thanks.

EDIT :
I found another solution which didn’t work either :

    public void SaveGame () {
        Player player = new Player{};
        Serializer.Save<Player>("save.txt", player);
        Debug.Log ("Saved");

With Serializer script as :

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

public class Serializer
{
    public static T Load<T>(string filename) where T: class
    {
        if (File.Exists(filename))
        {
            try
            {
                using (Stream stream = File.OpenRead(filename))
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    return formatter.Deserialize(stream) as T;
                }
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
            }
        }
        return default(T);
    }
  
    public static void Save<T>(string filename, T data) where T: class
    {
        using (Stream stream = File.OpenWrite(filename))
        {  
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, data);
        }
    }
}

In the end i get the same result as previoulsy, is save a .txt file with only the Class name inside. Look’s like i’m missing something.

I found the probleme about the Serialize option, it was saving an empty class because all my variables were static, so i just passed all of them public and make this change :

public class save_load : MonoBehaviour {



    public Player player_copy;
    private Player player_saver;
    // Use this for initialization
    void Start () {
        player_copy.lifetest8 = "Mewtwo";
        player_saver = player_copy;
        Debug.Log (player_saver.lifetest8);
        player_copy.lifetest8 = "Raichu";
        Debug.Log (player_saver.lifetest8);
    }

    public void LoadGame (){
        Player newSimpleClass = Serializer.Load<Player>("save.txt");
        Debug.Log (newSimpleClass.lifetest8);
    }

    public void SaveGame () {
        Serializer.Save<Player>("save.txt", player_saver);
        Debug.Log (player_saver);
        Debug.Log ("Saved");
}

Now i can use my “public” class Player without static variables in others script, modifing the copy also modifie the saver one, and the save/load method are working, its perfect ^^.

Well yeah. The static variables can’t change so there is no point in saving them.
Plus you don’t need an object reference to use the static variables.

Not entirely true, static variables can change just that they are not unique to one instance of a class but the class itself. You don’t need an instance of the object to access them. Constants are variables that can`t change value.

Most serializers I have played with ignore static variables when they serialize a class. Although there is probably a way to force it to serialize them.

Singalton just make a static variable that is a reference to 1 object of the same class

I confused static and const, how stupid of me.

This. Don’t make your player class static. While static members can change they should generally be thought of as immutable. So instead, use a regular POCO (plain old clr object a.k.a just a regular class) for your player and create some kind of Manager class if you want to have a static reference to it.