Save Hotbar between scenes

Gabtes

New member
Hi all,

I currently have the player's inventory persisting on scene changes with the included inventory saver, but I cannot seem to find any built-in option to do the same with the hotbar; currently it is wiped with every new scene change, despite the inventory persisting. Does this option exist or would I need to build my own?
For context, I am currently using the hotbar set up from the inventory manager which uses these components:
1676177245432.png

Thanks for the help! Hopefully not a silly request.
 
I don't know why I was convinced there was a ItemHotbarSaver but it turns out I was mistaken.
I'm surprised no one requested it before. We do have an InventoryGrid and ItemShapeGrid saver.

A work around (if it makes sense to you) is to use an Equipment panel rather than an ItemHotbar for your hotbar items. But of course that gives a different result so its not applicable in all scenevarios.

Please find the new ItemViewSlotsContainerSaver component below. I tested it in the demo scene on the ItemHotbar and it worked. Please do let me know if you find any bugs with this. it'll be available in the next update too.

You will need to make the "AssignItemToSlot" function public in both ItemViewSlotsContainerBase and ItemViewSlotsContainer scripts.
I hope that helps

Add the script in "Assets\Opsive\UltimateInventorySystem\Scripts\SaveSystem"

Also replace the meta file with this:
Code:
fileFormatVersion: 2
guid: 9b1966513a764f2da9c842d91150c07f
timeCreated: 1676281911

This way you won't have any issued when updating UIS.
 

Attachments

  • ItemViewSlotsContainerSaver.cs
    4.3 KB · Views: 2
I don't know why I was convinced there was a ItemHotbarSaver but it turns out I was mistaken.
I'm surprised no one requested it before. We do have an InventoryGrid and ItemShapeGrid saver.

A work around (if it makes sense to you) is to use an Equipment panel rather than an ItemHotbar for your hotbar items. But of course that gives a different result so its not applicable in all scenevarios.

Please find the new ItemViewSlotsContainerSaver component below. I tested it in the demo scene on the ItemHotbar and it worked. Please do let me know if you find any bugs with this. it'll be available in the next update too.

You will need to make the "AssignItemToSlot" function public in both ItemViewSlotsContainerBase and ItemViewSlotsContainer scripts.
I hope that helps

Add the script in "Assets\Opsive\UltimateInventorySystem\Scripts\SaveSystem"

Also replace the meta file with this:
Code:
fileFormatVersion: 2
guid: 9b1966513a764f2da9c842d91150c07f
timeCreated: 1676281911

This way you won't have any issued when updating UIS.
I tried to attach ItemViewSlotsContainerSaver to ItemHotbar object, but it could not work?
could you please explain more about how to use it to save ItemHotbar?

UPDATES
I figure out the reason is the order of start function. the character inventory's saver has yet loaded data when hotbar's is loading.
This could be a problem and may need extra logic to sort them.
 
Last edited:
So after discussing with @Justus on discord we found out the issue wasn't the save system manager loading order that was the problem, but rather that his hotbar and his player where not spawned within the same frame so the hotbar would always be loaded before the inventory since it was ticked as load on start.


So we decided to add some registering events such that you can wait until you have your expected object registered before loading the save data.

Here are the changes.

In the EventNames.cs script add these two:
Code:
//A new Saver was registered in the Save System Manager.
public const string c_OnSaverRegistered_SaverBase = "c_OnSaverRegistered_SaverBase";
//A saver was unregistered from the Save system Manager.
public const string c_OnSaverUnregistered_SaverBase = "c_OnSaverUnregistered_SaverBase";

Then in the SaveSystemManager script edit those two functions (RegisterSaverInternal and UnregisterSaverInternal):
Code:
/// <summary>
/// Register the saver components
/// </summary>
/// <param name="saver">The saver.</param>
protected virtual void RegisterSaverInternal(SaverBase saver)
{
    for (int i = 0; i < m_Savers.Count; i++) {
        if (m_Savers[i].FullKey != saver.FullKey) { continue; }
        if (m_Savers[i] != saver) {
            Debug.LogWarningFormat("Saver won't be registered because one with the same key is already registered");
        }
        return;
    }
    m_Savers.Add(saver);
    EventHandler.ExecuteEvent<SaverBase>(EventNames.c_OnSaverRegistered_SaverBase,saver);
}
/// <summary>
/// Unregister saver components
/// </summary>
/// <param name="saver">The saver.</param>
protected virtual void UnregisterSaverInternal(SaverBase saver)
{
    if (m_Savers.Contains(saver) == false) {
        return;
    }
    m_Savers.Remove(saver);
    EventHandler.ExecuteEvent<SaverBase>(EventNames.c_OnSaverUnregistered_SaverBase,saver);
}
 
Last edited:
I have noticed that this saver only seems to save/load once, and it will only keep track of the change you make in that scene. I'll try to show what I mean:
Scene A, item assigned to slot 1.
1677033819760.png
Scene B, item in slot 1 still. Different item assigned to slot 3.
1677034098639.png
Returning to Scene A, slot 3 has the item but the one in slot 1 is gone.
1677034129591.png

Here is what the component looks like. The key is the same on all scenes and I have played with some of the bools, but none seem to fix this.
1677034784358.png

All my other savers (position, inventory, equipment) are working as intended so I don't believe it's a problem with the setup of the save system itself. Let me know if this makes sense and thanks again!
 
That's very odd because the saver saves the state of the hotbar at the moment of saving and then loads the item in each slot at the moment of loading. It doesn't check for differences.
If you assign two different items to different slots does it do the same? Or does it only happen when its the same item in different slots?

I would recommenc adding a Debug.Log in the
SerializeSaveData and DeserializeAndLoadSaveData of the ItemViewSlotsContainerSaver just to see what items are being saved and loaded in your hotbar.
Because there is the possibility it is working fine but you have some other script somewhere that resets the first slot
 
I have noticed that this saver only seems to save/load once, and it will only keep track of the change you make in that scene. I'll try to show what I mean:
Scene A, item assigned to slot 1.
View attachment 10371
Scene B, item in slot 1 still. Different item assigned to slot 3.
View attachment 10372
Returning to Scene A, slot 3 has the item but the one in slot 1 is gone.
View attachment 10373

Here is what the component looks like. The key is the same on all scenes and I have played with some of the bools, but none seem to fix this.
View attachment 10374

All my other savers (position, inventory, equipment) are working as intended so I don't believe it's a problem with the setup of the save system itself. Let me know if this makes sense and thanks again!
============== One possible cause ============================
In my project, your use case could work perfectly.
My personal experiences:
1) Item View Slots Container Saver is not `standalone`, it always base on an inventory, so if your inventory `Load On Start`, but it's instantiated later than your hotbar, it may cause some problem
2) enable "Save On Destroy"

Summary
1) Enable `Save On Destroy` for all saver, their invoke order is trivial.
2) The Load timing is important, make sure target inventory's saver has executed load operation before Hotbar saver.


===================== Another Possible Root Cause of your case ================
I notice the refresh of hotbar will encount some issue if its option hasn't been setup properly.
Make sure enable hotbar's `draw on inventory update` option.
 
That's very odd because the saver saves the state of the hotbar at the moment of saving and then loads the item in each slot at the moment of loading. It doesn't check for differences.
If you assign two different items to different slots does it do the same? Or does it only happen when its the same item in different slots?

I would recommenc adding a Debug.Log in the
SerializeSaveData and DeserializeAndLoadSaveData of the ItemViewSlotsContainerSaver just to see what items are being saved and loaded in your hotbar.
Because there is the possibility it is working fine but you have some other script somewhere that resets the first slot
This behavior occurs regardless of slot, even if I only assign to 2/3 and leave 1 empty.
I tried adding debug.logs to both the save and load functions, specifically the for loops to see exactly what items were being recognized and loaded.
Here is what happened:
(Save)
1677087370404.png
(Load)
1677087395305.png
So exiting and loading a different scene, it recognized the item in slot 2 and saved/loaded correctly.
(Save)
1677087444014.png
(Load)
1677087456400.png
After adding a different item to slot 3 and leaving the scene again, it returned null for slot 2 even though I did not remove the item.


============== One possible cause ============================
In my project, your use case could work perfectly.
My personal experiences:
1) Item View Slots Container Saver is not `standalone`, it always base on an inventory, so if your inventory `Load On Start`, but it's instantiated later than your hotbar, it may cause some problem
2) enable "Save On Destroy"

Summary
1) Enable `Save On Destroy` for all saver, their invoke order is trivial.
2) The Load timing is important, make sure target inventory's saver has executed load operation before Hotbar saver.


===================== Another Possible Root Cause of your case ================
I notice the refresh of hotbar will encount some issue if its option hasn't been setup properly.
Make sure enable hotbar's `draw on inventory update` option.
Thanks for the info. Maybe this is an issue with load order? I previously tried checking save on destroy for the hotbar savers across the scenes and it did not change the outcome. How can I ensure the inventory is being loaded first, would that require something like a simple "WaitForFrames" coroutine in the hotbar saver or is there an existing setting that I am missing?
 
Top