Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Let us know a bit about your interests, and if you'd like to become more directly involved. Take our survey!
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Saving multiple data

Discussion in 'Scripting' started by ScamTheMan, Oct 13, 2018.

  1. ScamTheMan

    ScamTheMan

    Joined:
    Oct 4, 2018
    Posts:
    8
    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
     
  2. TwixEmma

    TwixEmma

    Joined:
    Jan 27, 2014
    Posts:
    228
    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):
    1.  
    2. /*SaveFile.cs
    3.     Written by Emma McTerrelly 13/10/2018
    4.  
    5.     Drop this script onto an empty GameObject.
    6.     Implement game saving behaviours that implement the SaveData class inheritance.
    7.     Drop those behaviours into the SaveableData array in this script in the inspector.
    8.     Then call the Save, SaveAs and Load methods from another script to handle your SaveFile.
    9.  
    10.     BinaryWriter hWriter {
    11.         hWriter.Write({ yourVar });
    12.     }
    13.     BinaryReader hReader {
    14.         bool hReader.ReadBoolean();
    15.         byte hReader.ReadByte();
    16.         byte[] hReader.ReadBytes(int count);
    17.         char hReader.ReadChar();
    18.         char[] hReader.ReadChars(int count);
    19.         decimal hReader.ReadDecimal();
    20.         double hReader.ReadDouble();
    21.         short hReader.ReadInt16();
    22.         int hReader.ReadInt32();
    23.         long hReader.ReadInt64();
    24.         float hReader.ReadSingle();
    25.         string hReader.ReadString();
    26.         ushort hReader.ReadUInt16();
    27.         uint hReader.ReadUInt32();
    28.         ulong hReader.ReadUInt64();
    29.         sbyte hReader.ReadSByte();
    30.     }
    31.  
    32.     //ExampleSaveFile.cs
    33.     //put this in it's own file and modify as you need to
    34.    
    35.     using System.Collections.Generic;
    36.     using UnityEngine;
    37.    
    38.     public class ExampleSaveFile : SaveData
    39.     {
    40.         //save data
    41.         public override bool Serialize(System.IO.BinaryWriter hWriter)
    42.         {
    43.             bool success = true;    //set to false if something goes wrong
    44.             //m_Name is inherited from the SaveData class
    45.             hWriter.Write(m_Name);
    46.             return success;
    47.         }
    48.  
    49.         //load data
    50.         public override bool Deserialize(System.IO.BinaryReader hReader)
    51.         {
    52.             bool success = true;    //set to false if something goes wrong
    53.             //m_Name is inherited from the SaveData class
    54.             m_Name = hReader.ReadString();
    55.             return success;
    56.         }
    57.     }
    58.  
    59. */
    60.  
    61. using System;
    62. using System.IO;
    63. using System.Collections.Generic;
    64. using UnityEngine;
    65.  
    66. //this class can be used to define a save file
    67. public class SaveFile : MonoBehaviour
    68. {
    69.     //the filename to save to or the filename last saved to
    70.    public string FileName;
    71.  
    72.     //all data references in the game to be saved
    73.     public SaveData[] SaveableData;
    74.  
    75.     //save all referenced game data to the filename stored
    76.     //returns true for success, false for error
    77.     //will also Debug.LogError any exceptions/errors
    78.     public bool Save()
    79.     {
    80.         bool success = !string.IsNullOrEmpty(FileName);
    81.         if (success)
    82.         {
    83.             try
    84.             {
    85.                 string backupFile = Path.Combine(FileName, ".bak");
    86.                 //if the filename exists, create a backup file
    87.                 if (File.Exists(FileName))
    88.                 {
    89.                     File.Copy(FileName, backupFile);
    90.                 }
    91.                 //create a new file or overwrite the existing file
    92.                 using (FileStream hFile = File.Create(FileName))
    93.                 {
    94.                     try
    95.                     {
    96.                         //use a binary writer to save game data to the file
    97.                         using (BinaryWriter hWriter = new BinaryWriter(hFile))
    98.                         {
    99.                             try
    100.                             {
    101.                                 //cycle through all saveable/loadable game data and write it to file
    102.                                 foreach (SaveData saveData in SaveableData)
    103.                                 {
    104.                                     saveData.Serialize(hWriter);
    105.                                 }
    106.                             }
    107.                             catch (Exception ex) //catch any error and report it
    108.                             {
    109.                                 Debug.LogError(ex.ToString());
    110.                                 success = false;
    111.                             }
    112.                             //close the binary writer stream
    113.                             hWriter.Close();
    114.                         }
    115.                     }
    116.                     catch (Exception ex)
    117.                     {
    118.                         Debug.LogError(ex.ToString());
    119.                         success = false;
    120.                     }
    121.                     //close the file
    122.                     hFile.Close();
    123.                 }
    124.                 //if something went wrong, restore the backup file
    125.                 if (!success)
    126.                 {
    127.                     try
    128.                     {
    129.                         File.Copy(backupFile, FileName);
    130.                     }
    131.                     catch(Exception ex)
    132.                     {
    133.                         Debug.LogError("Failed to Restore Backup File");
    134.                         Debug.LogError(ex.ToString());
    135.                     }
    136.                 }
    137.             }
    138.             catch (Exception ex) //catch any error and report it
    139.             {
    140.                 Debug.LogError(ex.ToString());
    141.                 success = false;
    142.             }
    143.         }
    144.         else
    145.         {
    146.             Debug.LogWarning("No FileName Provided");
    147.         }
    148.         return success;
    149.     }
    150.  
    151.     //load all the referenced game data from the stored filename
    152.     //returns true for success, false for error
    153.     //will also Debug.LogError any exceptions/errors
    154.     public bool Load()
    155.     {
    156.         //check if the file exists
    157.         bool success = File.Exists(FileName);
    158.         if (success)
    159.         {
    160.             try
    161.             {
    162.                 //open the file for reading
    163.                 using (FileStream hFile = File.OpenRead(FileName))
    164.                 {
    165.                     try
    166.                     {
    167.                         //use a binary reader to read all the saved game data from the file
    168.                         using (BinaryReader hReader = new BinaryReader(hFile))
    169.                         {
    170.                             try
    171.                             {
    172.                                 //cycle through all saveable/loadable game data and load it from the file
    173.                                 foreach (SaveData saveData in SaveableData)
    174.                                 {
    175.                                     saveData.Deserialize(hReader);
    176.                                 }
    177.                             }
    178.                             catch(Exception ex)
    179.                             {
    180.                                 Debug.LogError(ex.ToString());
    181.                                 success = false;
    182.                             }
    183.                             //close the binary reader stream
    184.                             hReader.Close();
    185.                         }
    186.                     }
    187.                     catch(Exception ex) //catch any error and report it
    188.                     {
    189.                         Debug.LogError(ex.ToString());
    190.                         success = false;
    191.                     }
    192.                     //close the file
    193.                     hFile.Close();
    194.                 }
    195.             }
    196.             catch(Exception ex) //catch any error and report it
    197.             {
    198.                 Debug.LogError(ex.ToString());
    199.                 success = false;
    200.             }
    201.         }
    202.         else
    203.         {
    204.             Debug.LogWarning("File '" + FileName + "' Not Found");
    205.         }
    206.         return success;
    207.     }
    208.  
    209.     //save all referenced game data to a specific filename
    210.     //stores the filename
    211.     //returns true for success, false for error
    212.     public bool SaveAs(string fileName)
    213.     {
    214.         FileName = fileName;
    215.         return Save();
    216.     }
    217. }
    218.  
    219. //all classes that need to save data should inherit from this class
    220. //and implement the serialize(save) and deserialize(load) methods as
    221. //public override bool Serialize(BinaryWriter hWriter) { }
    222. //public override bool Deserialize(BinaryReader hReader) { }
    223. //then those behaviours should be assigned in the inspector to the
    224. //SaveableData array in this script
    225. public abstract class SaveData : MonoBehaviour, ISerialize
    226. {
    227.     //having a name variable makes it easier to organise the saveable game data in the inspector
    228.     [SerializeField]
    229.     protected string m_Name;
    230.     public string Name { get { return m_Name; } }
    231.  
    232.     //this method writes the saveable/loadable game data to the binary file stream
    233.     public virtual bool Serialize(BinaryWriter hWriter)
    234.     {
    235.         throw new NotImplementedException();
    236.     }
    237.     //this method reads the saveable/loadable game data to the binary file stream
    238.     public virtual bool Deserialize(BinaryReader hReader)
    239.     {
    240.         throw new NotImplementedException();
    241.     }
    242. }
    243.  
    244. //generic serialization for reading and writing binary data interface
    245. //you don't need to do anything with this, this just makes magic!
    246. public interface ISerialize
    247. {
    248.     //having a name variable makes it easier to organise the saveable game data in the inspector
    249.     string Name { get; }
    250.     //this method is used to write the data you want to save
    251.     bool Serialize(BinaryWriter hWriter);
    252.     //this method is used to read the data you saved
    253.     bool Deserialize(BinaryReader hReader);
    254. }
    255.  
     
    Last edited: Oct 13, 2018