Loading game objects from the structure

Discussion and help for Easy Save 3
Rondol
Posts: 5
Joined: Tue Jan 23, 2024 9:30 am

Loading game objects from the structure

Post by Rondol »

I'm trying to save/load game objects from the structure

Code: Select all

public struct SaveDataStruct
{
    public DateTime SaveDate;
    public string SaveName;
    public List<GameObject> SaveObjects;
}
that's how I do the save\upload

Code: Select all

public List<GameObject> _saveObjectList;

...

public void SaveTest()
{
    var filename = $"{Application.dataPath}/Saves/123.sav";
    var data = new SaveDataStruct();

    data.SaveName = "123";
    data.SaveDate = DateTime.Now;
    data.SaveObjects = new List<GameObject>();

    foreach (GameObject list in _saveObjectList)
    {
        data.SaveObjects.Add(list);
    }

    ES3.Save("prefabInstances", data, filename);
}

public void LoadTest()
{
    var filename = $"{Application.dataPath}/Saves/123.sav";
    ES3.Load("prefabInstances", filename, new SaveDataStruct());
}
but the game objects (naturally) don't load. How do I load game objects (transforms and scripts for them) from the structure?

P S the ES3Prefab and ES3GameObject scripts are hanging on the objects
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Loading game objects from the structure

Post by Joel »

Hi there,

Fields of UnityEngine.Object types such as GameObjects will be saved and loaded by reference.

Is there any reason you're putting all of your save data into a struct and saving that, rather than just saving your Date, Name and GameObjects to separate keys? If you did this then the list of GameObjects would be saved by value, and would simplify your code.

If your intention is to have separate save slots then usually you would have each save slot as a separate file rather separate keys within the file.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Rondol
Posts: 5
Joined: Tue Jan 23, 2024 9:30 am

Re: Loading game objects from the structure

Post by Rondol »

Oh, thank you. I did this

Code: Select all

public void SaveTest()
{
    var filename = $"{Application.dataPath}/Saves/123.sav";

    var data = new List<GameObject>();

    foreach (GameObject list in _saveObjectList)
    {
        data.Add(list);
    }

    ES3.Save("Name", "123", filename, _saveSetting);
    ES3.Save("Date", DateTime.Now, filename, _saveSetting);
    ES3.Save("Data", data, filename, _saveSetting);
}

public void LoadTest()
{
    var filename = $"{Application.dataPath}/Saves/123.sav";
    var name = ES3.Load("Name", filename, _saveSetting);
    Debug.Log(name);
    var date = ES3.Load("Date", filename, _saveSetting);
    Debug.Log(date);
    var list = ES3.Load("Data", filename, new List<GameObject>(), _saveSetting);
}
thank you very much. I did the structure when I was trying to save data in another way, until I found out about your wonderful assets!
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Loading game objects from the structure

Post by Joel »

Glad that's all working for you now :) Note that you don't need to put your GameObjects into a List to save them. Another thing to note, you don't need to construct the full path yourself as Easy Save automatically makes paths relative to the persistent data path, and this also allows Easy Save to work on WebGL without special code. Both of these changes would look like this:

Code: Select all

public void SaveTest()
{
    var filename = "123.sav";

    ES3.Save("Name", "123", filename, _saveSetting);
    ES3.Save("Date", DateTime.Now, filename, _saveSetting);
    ES3.Save("Data", _saveObjectList, filename, _saveSetting);
}
Hope this helps!

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Rondol
Posts: 5
Joined: Tue Jan 23, 2024 9:30 am

Re: Loading game objects from the structure

Post by Rondol »

I apologize for writing to this topic again, I have a problem again. That's how I save it

Code: Select all

public bool TrySaveFile(string name)
{
    try
    {
        var filename = $"{Application.dataPath}/Saves/{name}.sav";
        var SaveScreen = _screenCamer.TrySaveCameraView(_camera);

        ES3.Save(_infoName, name, filename, _saveSetting);
        ES3.Save(_infoDate, DateTime.Now, filename, _saveSetting);
        ES3.Save(_infoScreen, SaveScreen, filename, _saveSetting);
        ES3.Save(_dataObject, _saveObjectList, filename, _saveSetting);

        return true;
    }
    catch (System.IO.IOException)
    {
        Debug.LogWarningFormat("The file is open elsewhere or there was not enough storage space");
        return false;
    }
    catch (System.Security.SecurityException)
    {
        Debug.LogWarningFormat("You do not have the required permissions");
        return false;
    }
}
That's how I load gameobject

Code: Select all

public bool TryLoadGameObject(string filename)
{
    try
    {
        var list = ES3.Load(_dataObject, filename, new List<GameObject>(), _saveSetting);
        return true;
    }
    catch (System.IO.IOException)
    {
        Debug.LogWarningFormat("The file is open elsewhere or there was not enough storage space");
        return false;
    }
    catch (System.Security.SecurityException)
    {
        Debug.LogWarningFormat("You do not have the required permissions");
        return false;
    }
}
and I get this warning:
FormatException: Expected '{' or "null", found ','.
ES3Internal.ES3JSONReader.ReadNullOrCharIgnoreWhitespace (System.Char expectedChar) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3JSONReader.cs:359)
ES3Internal.ES3JSONReader.StartReadObject () (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3JSONReader.cs:111)
ES3Types.ES3Type_GameObject.ReadComponents (ES3Reader reader, UnityEngine.GameObject go) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_GameObject.cs:198)
ES3Types.ES3Type_GameObject.ReadObject[T] (ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_GameObject.cs:176)
ES3Types.ES3ObjectType.ReadInto[T] (ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:75)
ES3Types.ES3Type_GameObject.ReadObject[T] (ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_GameObject.cs:136)
ES3Types.ES3ObjectType.Read[T] (ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:52)
ES3Reader.ReadObject[T] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:253)
ES3Reader.Read[T] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:282)
ES3Types.ES3CollectionType.ReadICollection[T] (ES3Reader reader, System.Collections.Generic.ICollection`1[T] collection, ES3Types.ES3Type elementType) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3CollectionType.cs:52)
ES3Types.ES3ArrayType.Read (ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3ArrayType.cs:36)
ES3Reader.Read[T] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:278)
ES3Reader.Read[T] () (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:126)
ES3Types.ES3Type_GameObject.ReadObject[T] (ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_GameObject.cs:169)
ES3Types.ES3ObjectType.ReadInto[T] (ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:75)
ES3Types.ES3Type_GameObject.ReadObject[T] (ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_GameObject.cs:136)
ES3Types.ES3ObjectType.Read[T] (ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:52)
ES3Reader.ReadObject[T] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:253)
ES3Reader.Read[T] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:282)
ES3Types.ES3ListType.Read (ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3ListType.cs:64)
ES3Reader.Read[T] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:278)
ES3Reader.Read[T] (System.String key, T defaultValue) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:216)
ES3.Load[T] (System.String key, T defaultValue, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:507)
ES3.Load[T] (System.String key, System.String filePath, T defaultValue, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:490)
SaveLoadCore.SaveLoad.TryLoadGameObject (System.String filename) (at Assets/Scripts/SaveSystem/SaveLoad.cs:90)
SaveLoadCore.UIView.LoadButton.ClickLoadButton () (at Assets/Scripts/UIManagers/LoadButton.cs:24)
UnityEngine.Events.InvokableCall.Invoke () (at <6afd1274f120405096bc1ad9e2010ba6>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <6afd1274f120405096bc1ad9e2010ba6>:0)
UnityEngine.UI.Button.Press () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:70)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:114)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Loading game objects from the structure

Post by Joel »

First try deleting your save data by going to Tools > Easy Save 3 > Clear Persistent Data Path.

Secondly, check you're only saving necessary components in your ES3GameObject (for example in your case the ES3Prefab and ES3GameObject components shouldn't be selected as they shouldn't change at runtime).

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Rondol
Posts: 5
Joined: Tue Jan 23, 2024 9:30 am

Re: Loading game objects from the structure

Post by Rondol »

I did everything as you wrote, but the problem persisted

And please tell me if I add a prefab to the scene in runtime, and then do ES3.Load(...) then the added prefab remains until the scene is reloaded.
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Loading game objects from the structure

Post by Joel »

Hi there,

Please could you replicate this in a new project with a simple scene and sent me a link to it on moodkie.com/contact along with step-by-step instructions on how to replicate the issue.
And please tell me if I add a prefab to the scene in runtime, and then do ES3.Load(...) then the added prefab remains until the scene is reloaded.
I'm not sure I understand what your question is. However, for information on saving and loading prefab instances please see the relevant guide:

https://docs.moodkie.com/easy-save-3/es ... 0instances

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Rondol
Posts: 5
Joined: Tue Jan 23, 2024 9:30 am

Re: Loading game objects from the structure

Post by Rondol »

I sorted out my mistakes, created a new empty project and everything worked. Now about what you didn't understand. There are 5 gameobjects in the scene, I save using the above method, add the 6th object and click load. I would like the object that was not saved before to disappear (because it was not there when saving it) how best to do this?
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Loading game objects from the structure

Post by Joel »

Hi there,

You would need to destroy the objects which were added yourself as there would be no way for Easy Save to know to do this. Generally you would put all of the objects which would need to be destroyed into a List, and clear this list when you save.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Post Reply