ApplyData data is null and GameObjects are not loading

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
hidingso
Posts: 26
Joined: Sat Sep 25, 2021 2:07 pm

ApplyData data is null and GameObjects are not loading

Post by hidingso »

Hello

I ran into a weird issue while restructuring my scene hierarchy.

I am using VS Code with Unity Debugger. My Unity version is 2021.1.17f1 and Dialogue System version is 2.2.18.

I start the game on StartScene, where I have my Dialogue Manager with Menu System and Save System (with PlayerPrefs Saved Game Data Storer).

I start my game and by pressing "Start" I load scene "Player" which acts as a persistent scene in my game, holding the player, camera, lights, and inventory in it.

I then additively load an environment scene based on what needs to be loaded.

When I start my game and pick up some items, they are added to the inventory well ok.
Inventory inventory = GetComponent<Inventory>();
return SaveSystem.Serialize(inventory);
When I save a game, all data seems to be saved properly
SavedGame1: {"m_sceneName":"Player","m_list":[{"key":"AlfonsoPosition","sceneIndex":1,"data":"{\"scene\":5,\"position\":{\"x\":874.1185913085938,\"y\":83.27227783203125,\"z\":-2190.5478515625},\"rotation\":{\"x\":0.0,\"y\":0.266330748796463,\"z\":0.0,\"w\":0.9638817310333252}}"},{"key":"Main Camera","sceneIndex":-1,"data":"{\"scene\":5,\"position\":{\"x\":871.164306640625,\"y\":85.48347473144531,\"z\":-2195.871337890625},\"rotation\":{\"x\":0.05638600513339043,\"y\":0.2501929700374603,\"z\":-0.014597225934267044,\"w\":0.9664424657821655}}"},{"key":"AdditiveSceneManager","sceneIndex":1,"data":"{\"Alfonso\":{\"instanceID\":2032734},\"Airplane\":{\"instanceID\":2032756},\"mainCamera\":{\"instanceID\":2018174},\"playerCam\":{\"instanceID\":2027974},\"BlackFade\":{\"instanceID\":2021468},\"circleTransitionController\":{\"instanceID\":0}}"},{"key":"AddedScenes","sceneIndex":1,"data":"{}"},{"key":"PlayerInventory","sceneIndex":1,"data":"{\"activeBody\":{\"instanceID\":62272},\"activeFront\":{\"instanceID\":0},\"activeTail\":{\"instanceID\":0},\"activeWings\":{\"instanceID\":0},\"activeWheels\":{\"instanceID\":0},\"activePropeller\":{\"instanceID\":0},\"activeMotor\":{\"instanceID\":0},\"items\":[],\"planeParts\":[{\"instanceID\":62260},{\"instanceID\":62262},{\"instanceID\":62264},{\"instanceID\":62266},{\"instanceID\":62268},{\"instanceID\":62270},{\"instanceID\":62272},{\"instanceID\":62274},{\"instanceID\":62276},{\"instanceID\":62278},{\"instanceID\":62280},{\"instanceID\":62282},{\"instanceID\":62284},{\"instanceID\":62286}]}"}]}
But when I try loading the game my Inventory GameObject does not get the data. There is only one Intenvory present in the game.

I tried debugging the ApplyData(string data) method inside the saver, and it seems the "data" string is null. I am not proficcient enough in C# to know if this means that the string is actually empty or the debugger just doesn't see it.

If I go back in the call stack, the Apply Data is called from SaveSystem with what looks like to be the proper SavedGameData

Image

Image

This is puzzling me, why is the data null all of a sudden?

I had the saving/loading working, but I had to refactor some stuff and decided to add the Menu System and Save System that are available on this site.
hidingso
Posts: 26
Joined: Sat Sep 25, 2021 2:07 pm

Re: ApplyData data is null and GameObjects are not loading

Post by hidingso »

Ok,

It seems like the "Save Current Scene" in Save System is the cause of this behavior.

savedGameData has 5 indexes in m_dict, but after line 717 in SaveSystem.cs

Code: Select all

instance.StartCoroutine(LoadSceneCoroutine(savedGameData, null));
m_dict only has 1 index. This is why my data string is null. Is this by design?

I noticed my savers "sceneIndex" variable was different in different savers (although they reside in the same "Player" scene). Does this play a role in the problem? I am wondering if the loading would work if sceneIndexes were different.
User avatar
Tony Li
Posts: 21981
Joined: Thu Jul 18, 2013 1:27 pm

Re: ApplyData data is null and GameObjects are not loading

Post by Tony Li »

Hi,

Tick the saver's 'Save Across Scene Changes' checkbox. Otherwise it will save the current scene's index and, if you load a scene that's not that index, it will clear the save data.
hidingso
Posts: 26
Joined: Sat Sep 25, 2021 2:07 pm

Re: ApplyData data is and GameObjects are not loading

Post by hidingso »

Tony Li wrote: Sun Feb 20, 2022 8:40 pm Hi,

Tick the saver's 'Save Across Scene Changes' checkbox. Otherwise it will save the current scene's index and, if you load a scene that's not that index, it will clear the save data.
Oh, that seemed to fix it. I thought the "Save Across Scene Changes" would save the data to the current PlayerPrefs slot? Is this incorrect?

Also, if it's ok to ask here: The writing custom savers part doesn't say much about saving references to other classes.

For example

Code: Select all


[Serializable]
public class SomeClass: MonoBehaviour
{
    public AnotherClass another;
}
I have hard time retrieving such references with Loaders, and no idea how to "correctly" serialize references to other objects. Is there some guidelines on how to handle such scenario?
User avatar
Tony Li
Posts: 21981
Joined: Thu Jul 18, 2013 1:27 pm

Re: ApplyData data is null and GameObjects are not loading

Post by Tony Li »

Hi,

"Save Across Scene Changes" affects the data before it even gets to a SavedGameDataStorer such as PlayerPrefsSavedGameDataStorer. The save system uses it to pare down data that it thinks it no longer needs. Ticking "Save Across Scene Changes" tells the save system that this data should never be cleared out due to a scene change.

Regarding references to other classes, most serializers don't handle references to other classes or other types of UnityObjects (such as ScriptableObjects). The save system's default JsonDataSerializer is no exception.

To save a connection to another class, you'll need to save a basic data type. For example, you could store a unique value such as GUID in AnotherClass:

Code: Select all

public class AnotherClass : MonoBehaviour
{
    public string myGuid;
    
    void Reset() // Unity automatically calls Reset() when adding a script to a GameObject or when resetting it.
    {
        myGuid = System.Guid.NewGuid().ToString();
    }
    
    ... (the rest of your script here)
}
You should serialize MonoBehaviours directly. Use an intermediate class for the save system. Open the PositionSaver.cs class for an example. For example, let's say it's called SomeClassSaveData:

Code: Select all

[Serializable]
public class SomeClassSaveData
{
    public string anotherClassGuid;
}
Your SomeClass can save and load like this:

Code: Select all

public override string RecordData()
{
    var saveData = new SomeClassSaveData();
    saveData.anotherClassGuid = another.myGuid; // (Should really check that another is assigned first.)
    return SaveSystem.Serialize(saveData);
}

public override void ApplyData(string s)
{
    // (Should really check that s isn't empty and that saveData is not null below.)
    var saveData = SaveSystem.Deserialize<SomeClassSaveData>(s);
    
    // Find our AnotherClass by guid:
    foreach (AnotherClass ac in FindObjectsOfType<AnotherClass>())
    {
        if (ac.guid == saveData.anotherClassGuid)
        {
            another = ac;
            break;
        }
    }
}
hidingso
Posts: 26
Joined: Sat Sep 25, 2021 2:07 pm

Re: ApplyData data is null and GameObjects are not loading

Post by hidingso »

Ok, that explains it! Big thanks for the answer!
User avatar
Tony Li
Posts: 21981
Joined: Thu Jul 18, 2013 1:27 pm

Re: ApplyData data is null and GameObjects are not loading

Post by Tony Li »

Glad to help!
Post Reply