Hello, I have a problem about saving my data in my game, I have about 30 different floats, ints and strings so I think saving it with DontDestroyOnLoad() isn't a best idea. I saw about 10 videos about it, but I think PlayerPrefs is for few variables and static is just for saving between scenes. So I saw a few videos on how to save data to XML files, but I always got lost in 45 minute videos. So wan't to ask, if there is a possible method to save this much variables and how to do it. And please mind that I script for about month, so I am not an expert. Thank you
Here's a file I wrote awhile ago, if it's any use to you please feel free to adapt it to your needs! Code (csharp): /*SaveFile.cs Written by Emma McTerrelly 13/10/2018 Drop this script onto an empty GameObject. Implement game saving behaviours that implement the SaveData class inheritance. Drop those behaviours into the SaveableData array in this script in the inspector. Then call the Save, SaveAs and Load methods from another script to handle your SaveFile. BinaryWriter hWriter { hWriter.Write({ yourVar }); } BinaryReader hReader { bool hReader.ReadBoolean(); byte hReader.ReadByte(); byte[] hReader.ReadBytes(int count); char hReader.ReadChar(); char[] hReader.ReadChars(int count); decimal hReader.ReadDecimal(); double hReader.ReadDouble(); short hReader.ReadInt16(); int hReader.ReadInt32(); long hReader.ReadInt64(); float hReader.ReadSingle(); string hReader.ReadString(); ushort hReader.ReadUInt16(); uint hReader.ReadUInt32(); ulong hReader.ReadUInt64(); sbyte hReader.ReadSByte(); } //ExampleSaveFile.cs //put this in it's own file and modify as you need to using System.Collections.Generic; using UnityEngine; public class ExampleSaveFile : SaveData { //save data public override bool Serialize(System.IO.BinaryWriter hWriter) { bool success = true; //set to false if something goes wrong //m_Name is inherited from the SaveData class hWriter.Write(m_Name); return success; } //load data public override bool Deserialize(System.IO.BinaryReader hReader) { bool success = true; //set to false if something goes wrong //m_Name is inherited from the SaveData class m_Name = hReader.ReadString(); return success; } } */ using System; using System.IO; using System.Collections.Generic; using UnityEngine; //this class can be used to define a save file public class SaveFile : MonoBehaviour { //the filename to save to or the filename last saved to public string FileName; //all data references in the game to be saved public SaveData[] SaveableData; //save all referenced game data to the filename stored //returns true for success, false for error //will also Debug.LogError any exceptions/errors public bool Save() { bool success = !string.IsNullOrEmpty(FileName); if (success) { try { string backupFile = Path.Combine(FileName, ".bak"); //if the filename exists, create a backup file if (File.Exists(FileName)) { File.Copy(FileName, backupFile); } //create a new file or overwrite the existing file using (FileStream hFile = File.Create(FileName)) { try { //use a binary writer to save game data to the file using (BinaryWriter hWriter = new BinaryWriter(hFile)) { try { //cycle through all saveable/loadable game data and write it to file foreach (SaveData saveData in SaveableData) { saveData.Serialize(hWriter); } } catch (Exception ex) //catch any error and report it { Debug.LogError(ex.ToString()); success = false; } //close the binary writer stream hWriter.Close(); } } catch (Exception ex) { Debug.LogError(ex.ToString()); success = false; } //close the file hFile.Close(); } //if something went wrong, restore the backup file if (!success) { try { File.Copy(backupFile, FileName); } catch(Exception ex) { Debug.LogError("Failed to Restore Backup File"); Debug.LogError(ex.ToString()); } } } catch (Exception ex) //catch any error and report it { Debug.LogError(ex.ToString()); success = false; } } else { Debug.LogWarning("No FileName Provided"); } return success; } //load all the referenced game data from the stored filename //returns true for success, false for error //will also Debug.LogError any exceptions/errors public bool Load() { //check if the file exists bool success = File.Exists(FileName); if (success) { try { //open the file for reading using (FileStream hFile = File.OpenRead(FileName)) { try { //use a binary reader to read all the saved game data from the file using (BinaryReader hReader = new BinaryReader(hFile)) { try { //cycle through all saveable/loadable game data and load it from the file foreach (SaveData saveData in SaveableData) { saveData.Deserialize(hReader); } } catch(Exception ex) { Debug.LogError(ex.ToString()); success = false; } //close the binary reader stream hReader.Close(); } } catch(Exception ex) //catch any error and report it { Debug.LogError(ex.ToString()); success = false; } //close the file hFile.Close(); } } catch(Exception ex) //catch any error and report it { Debug.LogError(ex.ToString()); success = false; } } else { Debug.LogWarning("File '" + FileName + "' Not Found"); } return success; } //save all referenced game data to a specific filename //stores the filename //returns true for success, false for error public bool SaveAs(string fileName) { FileName = fileName; return Save(); } } //all classes that need to save data should inherit from this class //and implement the serialize(save) and deserialize(load) methods as //public override bool Serialize(BinaryWriter hWriter) { } //public override bool Deserialize(BinaryReader hReader) { } //then those behaviours should be assigned in the inspector to the //SaveableData array in this script public abstract class SaveData : MonoBehaviour, ISerialize { //having a name variable makes it easier to organise the saveable game data in the inspector [SerializeField] protected string m_Name; public string Name { get { return m_Name; } } //this method writes the saveable/loadable game data to the binary file stream public virtual bool Serialize(BinaryWriter hWriter) { throw new NotImplementedException(); } //this method reads the saveable/loadable game data to the binary file stream public virtual bool Deserialize(BinaryReader hReader) { throw new NotImplementedException(); } } //generic serialization for reading and writing binary data interface //you don't need to do anything with this, this just makes magic! public interface ISerialize { //having a name variable makes it easier to organise the saveable game data in the inspector string Name { get; } //this method is used to write the data you want to save bool Serialize(BinaryWriter hWriter); //this method is used to read the data you saved bool Deserialize(BinaryReader hReader); }