- Home /
Save and load system not working please help
I have no idea why but my save and load system (based on the one seen here) has stopped working. I ran a test with it when I first finished writing it but it's stopped working for (probably a lot of) reasons which I can't figure out, the problem is that it's a logic error and I'm not getting much to go off, plus there's a LOT of code involved. Here's just the code involved with the primary saving and loading, if anyone asks for the other classes referenced I'll send it, just please help.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SettingAndValue : MonoBehaviour
{
//Creates values that need to be saved in settings
//Decided whether videos will loop
public static bool Loop = true;
//Creates values that will be saved between pages
public static string[] ValueStringArray = TempValueHandler.ValueStringArray;
public static int ValueInt = TempValueHandler.ValueInt;
//Creates values that store tags
public static List<string> A = TagHandler.A;
public static List<string> B = TagHandler.B;
public static List<string> C = TagHandler.C;
public static List<string> D = TagHandler.D;
public static List<string> E = TagHandler.E;
public static List<string> F = TagHandler.F;
public static List<string> G = TagHandler.G;
public static List<string> H = TagHandler.H;
public static List<string> I = TagHandler.I;
public static List<string> J = TagHandler.J;
//Creates values related to password protection
public static List<string> Passwords = PasswordHandler.Passwords;
public static List<string> PassProt = PasswordHandler.PassProt;
public static Dictionary<string, string> PassKey = PasswordHandler.PassKey;
public static List<string> PassUnlock = PasswordHandler.PassUnlock;
//Creates values related to file sorting/searching
public static Dictionary<string, List<string>> FileDictionary = SortingHandler.FileDictionary;
public void SaveState(SettingAndValue saver)
{
SaveSystem.SaveGameData(saver);
}
public static void LoadSettings()
{
SaveData data = SaveSystem.LoadSave();
Loop = data.Loop;
Debug.Log("Settings Data Loaded");
}
public static void LoadTempValues()
{
SaveData data = SaveSystem.LoadSave();
ValueStringArray = data.ValueStringArray;
ValueInt = data.ValueInt;
Debug.Log("TempValue Data Loaded");
}
public static void LoadTags()
{
SaveData data = SaveSystem.LoadSave();
A = data.A;
B = data.B;
C = data.C;
D = data.D;
E = data.E;
F = data.F;
G = data.G;
H = data.H;
I = data.I;
J = data.J;
Debug.Log("Tag Data Loaded");
}
public static void LoadPasswordSettings()
{
SaveData data = SaveSystem.LoadSave();
Passwords = data.Passwords;
PassProt = data.PassProt;
PassKey = data.PassKey;
PassUnlock = data.PassUnlock;
Debug.Log("Password Data Loaded");
}
public static void LoadSortSearch()
{
SaveData data = SaveSystem.LoadSave();
FileDictionary = data.FileDictionary;
Debug.Log("Sorting Data Loaded");
}
public void LoadAll()
{
LoadSettings();
LoadTempValues();
LoadTags();
LoadPasswordSettings();
LoadSortSearch();
Debug.Log("All Data Loaded");
}
}
You haven't really provided much to go off - what exactly is happening that isn't supposed to? How are you using the system? What is it supposed to do? etc.
@Namey5 The method "SaveState" when called should save all of the variables which are deter$$anonymous$$ed using separate c# scripts (ex. PasswordHandler.Passwords). Currently "SaveState" is tied to a button in my testing screen. The load methods such as "LoadAll" should load all of the data related to the variables associated with it. Currently the "LoadAll" method is also tied to a button in my testing screen. I've been testing the save system in the testing screen by adding tags to the list called "A" then saving. Then in theory , if I removed all the tags from the list and then hit the load button the list should once again contain all of the tags it held when I pressed the save button. But in reality nothing happens. When I hit the load button I get all of the Debug.Log messages confir$$anonymous$$g the methods were called but that's it, nothing changes. There's no error message, nothing, the data simply doesn't change, the variables stay as they are as though no method has been called.
What are you passing as the SettingAndValue parameter into the SaveState function? I'm assu$$anonymous$$g this is called via a Unity UI button event, and that the parameter should be the same object as the enclosing class, so I don't see a reason you need to pass another instance in over just referencing it directly;
public void SaveState()
{
SaveSystem.SaveGameData(this);
}
In fact, without seeing SaveSystem.SaveGameData() I'm not entirely sure what the purpose of passing the instance to the function is at all if all of the fields and methods are static?
Answer by Namey5 · Aug 18, 2021 at 09:42 AM
It seems redundant to me to have the exact same data layout in multiple places - instead what you can do is keep an instance of the SaveData class in your SettingAndValue script directly (and even make it static!) then just pass that to the save function directly.
First up, lets keep a static instance of SaveData in the SettingAndValue class and just work directly with that;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SettingAndValue : MonoBehaviour
{
public static SaveData GlobalSaveData = new SaveData ();
public void SaveState ()
{
// Send the save data directly
SaveSystem.SaveGameData (GlobalSaveData);
}
public void LoadAll ()
{
// Just update our GlobalSaveData directly from the file
GlobalSaveData = SaveSystem.LoadSave ();
Debug.Log("All Data Loaded");
}
}
From there, we need to rework the SaveSystem script a bit to use the SaveData as a parameter rather than SettingAndValue;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static class SaveSystem
{
// Pass the SaveData in directly
public static void SaveGameData (SaveData save)
{
BinaryFormatter formatter = new BinaryFormatter();
string path = Application.persistentDataPath + "/testSave.qul";
FileStream stream = new FileStream(path, FileMode.Create);
// Use the SaveData directly instead of making a new one
formatter.Serialize(stream, save);
stream.Close();
}
public static SaveData LoadSave ()
// ...
}
And finally, we can just remove the SettingAndValue constructor from the SaveData class as it is now just a data holder - also move the field initializers from SettingAndValue in here so that the variables have data by default;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SaveData
{
//Creates values that need to be saved in settings
//Decided whether videos will loop
public bool Loop = true;
//Creates values that will be saved between pages
public string[] ValueStringArray = TempValueHandler.ValueStringArray;
public int ValueInt = TempValueHandler.ValueInt;
//Creates values that store tags
public List<string> A = TagHandler.A;
public List<string> B = TagHandler.B;
public List<string> C = TagHandler.C;
public List<string> D = TagHandler.D;
public List<string> E = TagHandler.E;
public List<string> F = TagHandler.F;
public List<string> G = TagHandler.G;
public List<string> H = TagHandler.H;
public List<string> I = TagHandler.I;
public List<string> J = TagHandler.J;
//Creates values related to password protection
public List<string> Passwords = PasswordHandler.Passwords;
public List<string> PassProt = PasswordHandler.PassProt;
public Dictionary<string, string> PassKey = PasswordHandler.PassKey;
public List<string> PassUnlock = PasswordHandler.PassUnlock;
//Creates values related to file sorting/searching
public Dictionary<string, List<string>> FileDictionary = SortingHandler.FileDictionary;
}
Now, if you wish to access the saved fields, you can access them via the GlobalSaveData variable;
List<string> tagsA = SettingAndValue.GlobalSaveData.A;
Ok, this looks really good, but I'm getting a bit tripped up about what I should do in SettingAndValue. I've tried my best to copy down all of the changes you've recommended, but I'm getting an error in SaveState saying "cannot convert from 'SaveData' to 'SettingAndValue'" which I think has something to do with GlobalSaveData being a "new SaveData". I'm still not clear on exactly how GlobalSaveData works or what it really is. Either way thanks a whole lot for doing this much to help me out already, this whole saving problem has stumped me for weeks longer than any other problem I've ever faced before while learning to code, and it really means a lot to have help from someone who seems to know a lot more than I do.
Take a look at the SaveSystem.SaveGameData() function - we don't pass in a SettingAndValue object any more and instead pass in a SaveData object (in this case GlobalSaveData). That SaveData is then used directly rather than creating a new one from the SettingAndValue.
My SaveState function looks like this rn, is this wrong?
public static SaveData GlobalSaveData = new SaveData();
public void SaveState()
{
// Send the save data directly
SaveSystem.SaveGameData(GlobalSaveData);
}
Your answer
Follow this Question
Related Questions
Saving Melee Combat Template Pack (MY LAST PROBLEM) 1 Answer
How do I make a basic easy Save and load function with JavaScript 1 Answer
Problem with saving and loading game timer 0 Answers
Checkpoint autosave Method? 0 Answers
Save and load a class 0 Answers