Getting inventory to persist between scenes

Announcements, support questions, and discussion for the Dialogue System.
Peter Drake
Posts: 37
Joined: Tue May 17, 2022 3:49 pm

Getting inventory to persist between scenes

Post by Peter Drake »

I'm using Dialogue System with More Mountains' TopDown Engine and Inventory System. My challenge right now is to get inventory to persist between scenes. I want use DS's save system, because (by using PlayerPrefs) it should work for a WebGL game hosted on itch.io.

My previous attempt (https://www.pixelcrushers.com/phpbb/vie ... f=3&t=5473) became hopelessly entangled, so I decided to go back and start from a (relatively) blank slate.

I've set up an Inventory:
Screen Shot 2022-05-22 at 11.13.45 AM.png
Screen Shot 2022-05-22 at 11.13.45 AM.png (42.88 KiB) Viewed 1348 times
I think I've added all of the required components to my DialogueManager:
Screen Shot 2022-05-22 at 11.18.06 AM.png
Screen Shot 2022-05-22 at 11.18.06 AM.png (85.93 KiB) Viewed 1348 times
My trigger to change scenes just calls SceneManager.LoadScene(SceneName);.

I can walk between scenes, but anything I've picked up in the previous scene is no longer in my inventory. No error messages. (This is in the editor, not in a web build.)

What did I miss?
User avatar
Tony Li
Posts: 21975
Joined: Thu Jul 18, 2013 1:27 pm

Re: Getting inventory to persist between scenes

Post by Tony Li »

Hi,

- Your Dialogue Manager GameObject has two Dialogue System Savers. Remove one. Make sure the remaining one has a unique key such as "ds".

- On your PlayerInventory GameObject:
  • On the Dialogue System Inventory Event Listener component, keep Handle MM Save Load Events UNticked.
  • Add an Inventory Engine Saver component. Assign a unique key such as "playerInventory".
- Keep the changes you made to MMSceneLoadingManager subclass, and use that subclass instead of MMSceneLoadingManager in your LoadingScreen scene.
Peter Drake
Posts: 37
Joined: Tue May 17, 2022 3:49 pm

Re: Getting inventory to persist between scenes

Post by Peter Drake »

Tony Li wrote: Sun May 22, 2022 4:00 pm Hi,

- Your Dialogue Manager GameObject has two Dialogue System Savers. Remove one. Make sure the remaining one has a unique key such as "ds".
Huh, weird -- several components were duplicated. I removed the duplicates.
- On your PlayerInventory GameObject:
  • On the Dialogue System Inventory Event Listener component, keep Handle MM Save Load Events UNticked.
  • Add an Inventory Engine Saver component. Assign a unique key such as "playerInventory".
Done.
- Keep the changes you made to MMSceneLoadingManager subclass, and use that subclass instead of MMSceneLoadingManager in your LoadingScreen scene.
I don't have a LoadingScreen scene. Is that okay? (I'm hoping to avoid the MMSceneLoadingManager entirely by just calling SceneManager.LoadScene.)

Still no luck on getting the inventory items to stick around. Next suggestion?
Peter Drake
Posts: 37
Joined: Tue May 17, 2022 3:49 pm

Re: Getting inventory to persist between scenes

Post by Peter Drake »

I'm tanalizingly close. I decided to look at the DS demo scene, which of course uses a completely different technique: a Dialogue System Trigger. I made one for my level exit collider trigger object:
Screen Shot 2022-05-22 at 4.01.49 PM.png
Screen Shot 2022-05-22 at 4.01.49 PM.png (84.66 KiB) Viewed 1342 times
Does it work now? Almost! Here's what happens:

Start in Scene1 and pick up the knife. It's in my inventory.

Go to Scene1b through the exit. The knife is still in my inventory. Hooray!

Pick up the flashlight. Now I have two things in my inventory.

Go back to Scene1. They're both still there!

Go back to Scene1b. Now my inventory looks empty again, but in the Inspector the items are there:
Screen Shot 2022-05-22 at 4.05.31 PM.png
Screen Shot 2022-05-22 at 4.05.31 PM.png (325.59 KiB) Viewed 1342 times
This smells like a race condition where perhaps the visual elements didn't exist at the time the inventory tried to connect with them.

Now what?
User avatar
Tony Li
Posts: 21975
Joined: Thu Jul 18, 2013 1:27 pm

Re: Getting inventory to persist between scenes

Post by Tony Li »

Hi,
To answer this one first:
Peter Drake wrote: Sun May 22, 2022 4:22 pmI don't have a LoadingScreen scene. Is that okay? (I'm hoping to avoid the MMSceneLoadingManager entirely by just calling SceneManager.LoadScene.)
That's fine, but instead of SceneManager.LoadScene use SaveSystem.LoadScene. It takes care of saving and restoring data, too.
Peter Drake wrote: Sun May 22, 2022 7:08 pm...Go back to Scene1b. Now my inventory looks empty again, but in the Inspector the items are there: <image>

This smells like a race condition where perhaps the visual elements didn't exist at the time the inventory tried to connect with them.
If there aren't any errors or warnings in the Console, set the Save System's Frames To Wait Before Apply Data to 1. This will wait a frame to allow components to initialize.
Peter Drake
Posts: 37
Joined: Tue May 17, 2022 3:49 pm

Re: Getting inventory to persist between scenes

Post by Peter Drake »

Okay, the script attached to my exit trigger is now:

Code: Select all

using PixelCrushers;
using UnityEngine;

// A script is necessary here because a static method can't be called directly from Unity.
public class SceneLoader : MonoBehaviour
{

    public string SceneName;
    
    public void OnTriggerEnter(Collider other)
    {
        SaveSystem.LoadScene(SceneName);
    }
    
}
No errors or warning, Frames To Wait is set to 1. No joy.

Next?
Peter Drake
Posts: 37
Joined: Tue May 17, 2022 3:49 pm

Re: Getting inventory to persist between scenes

Post by Peter Drake »

Here's something interesting. I checked "debug" on the SaveSystem, and when I returned to Scene1 (where my inventory isn't displaying properly), it looks like Scene1 is being loaded TWICE:
Screen Shot 2022-05-22 at 4.54.10 PM.png
Screen Shot 2022-05-22 at 4.54.10 PM.png (25.76 KiB) Viewed 1340 times
That might be the problem, but why would it be happening? (I only have one Save System attached to the Dialogue Manager.)
User avatar
Tony Li
Posts: 21975
Joined: Thu Jul 18, 2013 1:27 pm

Re: Getting inventory to persist between scenes

Post by Tony Li »

That's probably causing the issue, since it may be saving the scene's data immediately after loading the scene instead of after the in-memory save data has been applied to the scene.

Please click on each of those two "Save System: Loading scene Scene1" messages, press Ctrl+C / Cmd+C to copy its details to the clipboard, then paste them into a reply. The details will show the stack trace of method calls that led to the scene load.
Peter Drake
Posts: 37
Joined: Tue May 17, 2022 3:49 pm

Re: Getting inventory to persist between scenes

Post by Peter Drake »

They are identical:

Code: Select all

Save System: Loading scene Scene1
UnityEngine.Debug:Log (object)
PixelCrushers.SaveSystem/<LoadSceneCoroutine>d__114:MoveNext () (at Assets/Plugins/Pixel Crushers/Common/Scripts/Save System/SaveSystem.cs:788)
UnityEngine.MonoBehaviour:StartCoroutine (System.Collections.IEnumerator)
PixelCrushers.SaveSystem:LoadScene (string) (at Assets/Plugins/Pixel Crushers/Common/Scripts/Save System/SaveSystem.cs:782)
SceneLoader:OnTriggerEnter (UnityEngine.Collider) (at Assets/Scripts/SceneLoader.cs:12)
User avatar
Tony Li
Posts: 21975
Joined: Thu Jul 18, 2013 1:27 pm

Re: Getting inventory to persist between scenes

Post by Tony Li »

Hi,

In your SceneLoader script, disable the collider to prevent it from triggering again (e.g., by a different collider) while you're already loading a scene.
Post Reply