Is it possible to save objects that are disabled in the hierarchy?

Hey,

@Brian_Trotter as you mentioned, I am making a community post about my question that I asked in the discord server earlier.

For context, I have make a prefab that acts as a “Familiar”. It has an AIFollower.sc script on it alongside other things to make it work.
It also has an Inventory.cs script on it, because I followed your guide on how to make multiple inventory containers, and I also made it possible for my Familiar to be able to equip / remove items and equipment from him.

The familiar is present in the Core prefab, because It will always be there, in any scene, ready to be enabled when “summoned”. It is enabled when the player will use a specific ability that I have created.
I didn’t want it to be Instantiated / Destroyed, because of how some various UI elements and components tied to its ability bar / inventory and equipment slots works.

Because of this, in this following scenario, if I move some items into my Familiars inventory, but I forget to save the game, then I dismiss it, making it go from enabled to disabled, If I go into a different scene, or even if I manually save, after the other scene is loaded ( or I continue the save), if I decide to summon my Familiar again (make it enabled from disabled), I will have the beautiful surprise of my item being gone.

So after this scenario, I realized that disabled objects don’t actually get saved.

Do you think that there is a workaround to enable at least the Familiar object to be saved even when it’s disabled in the hierarchy? I think that when when I was trying things, the Start method somehow could detect the disabled object in the hierarchy.

Thanks.

This is an interesting scenario, to say the least. In most cases, it is absolutely true, a disabled GameObject won’t get swept up by a FindObjectOfType, it’s simply how the system is designed. Fortunately, this scenario is specific enough to craft a solution. Rather than letting the Saving System sweep up the Familiar, we’re going to take care of it within the Player itself. Here’s what you’ll need to do:

First: Add a field to the SaveableEntity script:

[SerializedField] bool isManaged=false;
public bool IsManaged=>isManaged;

And in SavingSystem, in CaptureState, in the foreach loop add the following line:

if (saveable.IsManaged) continue;

This will force the system to ignore the Familiar whether it is enabled or not.
Finally, some more additions to SaveableEntity:

[SerializedField] List<SaveableEntity> entitiesToManage = new List<SaveableEntity>();

and finally some changes to CaptureState and RestoreState:

    public object CaptureState()
    {
        Dictionary<string, object> state = new Dictionary<string, object>();
        foreach (ISaveable saveable in GetComponents<ISaveable>())
        {
            state[saveable.GetType().ToString()] = saveable.CaptureState();
        }
        foreach(SaveableEntity entity in entitiesToManage)
        {
               state[entity.GetUniqueIdentifier()] = entity.CaptureState();
        }
        return state;
    }

    public void RestoreState(object state)
    {
        Dictionary<string, object> stateDict = (Dictionary<string, object>)state;
        foreach (ISaveable saveable in GetComponents<ISaveable>())
        {
            string typeString = saveable.GetType().ToString();
            if (stateDict.ContainsKey(typeString))
            {
                saveable.RestoreState(stateDict[typeString]);
            }
        }
        foreach (SaveableEntity entity in entitesToManage)
       {
             if(stateDict.ContainsKey(entity.GetUniqueIdentifier())
            {
                 entity.RestoreState(stateDict[entity.GetUniqueIdentifier()];
            }
        }
    }

So here’s what should happen:
The Familiar should have the “isManaged” checked.
The Player’s SaveableEntity should have the Familiar dragged into the list of managed entities (I made it a list because this trick is useful for many other things).

The Saving System will completely ignore the Familiar, because it sees that it “isManaged” .

Since the player’s SaveableEntity has a reference to the familiar, it can capture and restore the state of the Familiar, regardless of the status of said Familiar.

1 Like

@Brian_Trotter I forgot to mention a crucial thing, I am using your new JSon saving system from the conversion tutorial that you made :(.

But it was straight forward, and implemented it for the JSon system, and it works!! I had made a workaround for the time being, but I simply setup the familiar as managed and put it in my players list, then I moved some items in its inventory, disabled it, saved, then when I reloaded, the items were there!

Thanks a lot Brian, I can see that this solution that you made can have a lot of benefits for future uses!

It’s especially useful for spawned mobs that regenerate after a set period of time. For these, you would have a Manager that is responsible for spawning/respawning mobs and tracking their status.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.