Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Multi-Save System with save info displayed on UI - Json + ScriptableObject

Discussion in 'Scripting' started by mikeohc, Jan 16, 2021.

  1. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    I've got a multi-save system with save info displayed on UI working using Json for saving and Scriptable Object to display the info.

    Screenshot (5).png

    The problem is that this system will break when the player's save file count != to the file naming structure. e.g. allSaves.Length = 2, with names Save0.sav and Save3.sav will break the system. Though this can only happen when players edit save names themselves.

    This is because to display the info, I use one Scriptable Object (_playerProfile) that get overwritten in a for loop:
    Code (CSharp):
    1. public void LoadFromJson()
    2.     {
    3.         if (File.Exists(saveDataPath))
    4.         {
    5.             string playerData = File.ReadAllText(saveDataPath);
    6.             JsonUtility.FromJsonOverwrite(playerData, _playerProfile);
    7.         }
    8.  
    9.     }
    Code (CSharp):
    1. //another method for displaying UI
    2. for (int i = 0; i < allSaves.Length; i++)
    3.         {
    4.             saveDataPath = Application.dataPath + "/Saves/Save" + CurrentSave + ".sav";
    5.             LoadFromJson();
    6.             CurrentSave++;
    7.  
    8.             //Update UI etc.
    9.         }

    My current idea is to maybe loop through all files in the directory but I'm not sure how I'd increment the files in the loop to overwrite the _playerProfile scriptable object.
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Definitely just loop through the files in the directory. You'll need the System.IO namespace.

    Code (csharp):
    1.  
    2. using System.IO; // at the top with the other using statements
    3.  
    4.  
    5. string [] files = Directory.GetFiles(Path.Combine(Application.dataPath, "Saves"), "*.sav");
    6.  
    7. foreach(string file in files)
    8. {
    9.    // check if it's a real save file
    10.  
    11.    // process it as appropriate
    12. }
    13.  
     
    Last edited: Jan 21, 2021
    mikeohc likes this.
  3. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    Thank you, foreach didn't cross my mind for some reason. I'll have to rework the system later.

    How would creating a new save work? I've seen games where players add a Save99.sav, and the game will just increment Save0.sav to Save1.sav. while also loading Save99.sav. How is this logic achieved?
     
  4. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Every game is going to be unique in how it approaches naming their save files. If it's not tied to any sort of profile or anything like that, I'd simply use a timestamp for the name. Something like:
    Code (csharp):
    1.  
    2. string name = DateTime.Now.ToFileTime().ToString() + ".sav";
    3.  
    If you absolutely have to have it increment by number for some reason, you'll have to do some string manipulation by removing the "Save" and ".sav" and using int.TryParse(). Honestly that just feels like more headache than it's worth and if people are editing the file names anyways, no solution you concoct will protect your code from that so I'd just use something more bulletproof that doesn't rely on certain names in the first place.
     
    mikeohc likes this.