Save/Load Items across scene

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
kenlem
Posts: 25
Joined: Sun Aug 16, 2020 5:19 pm

Save/Load Items across scene

Post by kenlem »

Hi,

I want to have object persistence like in Fallout 3 and such where you can pick up an object in one level and drop it in another.

I'm trying to figure out how to use the save/load system to have objects move between levels if they are in your inventory. I'm working on a VR game using Dialogue System and Ultimate Inventory. I won't be using the GUI as you'll physically add and remove items from a backpack.

I have the save/load system working nicely for single levels. I want to be able to pick up one object in one level, add it to the backpack then be able drop it in another level and have it be saved there.

I have a main scene that loads first and contains everything I need for the game set to do not destroy. I have a Spawned Object Manager there. The main scene loads first then loads in levels as needed.

Levels have objects in them with position savers. Right now, that all works great. I leave scene and come back and objects are in new positions if they were previously moved.

I can pick up an object and add it my backpack. I have events that fire so the object gets added to Ultimate Inventory. This way I have a list of everything in my inventory. When I change scenes, I can see my inventory list is being saved and reloaded like I expect. Of course, that's just the list of what's in inventory and not real objects.

I was thinking that on level save before data is written, I would look at all the objects in the backpack. If an object in the backpack was loaded with this level, I would set it's Active Saver to false. If the object was instantiated, I would destroy it.

Then on load, I would go through the inventory list and instantiate any objects needed. I then want to be able to pull something out of inventory and drop in this new scene.

I hope I described that properly. Any suggestions?
User avatar
Tony Li
Posts: 21684
Joined: Thu Jul 18, 2013 1:27 pm

Re: Save/Load Items across scene

Post by Tony Li »

I recommend using your SpawnedObjectManager instead of PositionSaver/ActiveSaver. Essentially what you're doing when you drop an item into the world is spawning it into the scene. The SpawnedObjectManager will remember that you've spawned the object. As you leave the scene, it will record a list of all objects that you've spawned into the scene and their positions. When you return to the scene, the SpawnedObjectManager will respawn prefabs in those recorded positions.
kenlem
Posts: 25
Joined: Sun Aug 16, 2020 5:19 pm

Re: Save/Load Items across scene

Post by kenlem »

Well, that was easy. Thanks. I am now able to move spawned items between scenes.

When I put an object in my inventory, I disable the SpawnedObject component and the object in my inventory doesn't get saved, which is the correct behavior. I then load into another scene and take the object out of inventory being sure to enable the SpawnedObject saver. If I leave that scene and go back to the first, the original objects isn't there. If I move back to the 2nd scene the object is where I left it. All good.

Of course, this doesn't save the object if it's in my inventory. That's fine for now as I think I can deal with spawning the correct inventory objects later. I'm using Ultimate Inventory, so I just save the list of what's in inventory and spawn and destroy items as needed to sync the inventory in the scene with the inventory list Ultimate Inventory tracks.


THIS IS WHAT I'VE TRIED SO FAR THAT HASN'T WORKED:
I want to be able to decorate a scene in the editor with object prefabs that can then be moved to other scenes. I created a prefab of a ball:
a) Tagged as peristentObject
b) Has a active saver component
c) Has a disabled SpawnedObject component
d) Has an enabled saver pointing the the SpawnedObject component

I hooked up an event on OnSaveDataApplied that finds all these objects that were manually played in the editor by tag, spawns copies, then sets the original objects to active = false. The original objects has a destructible savers on them so spawn copies should only be created the first time a level is loaded. Haven't really gotten this to work. It copies the object each time the level is loaded.

Does that make sense? Can you think of a way to decorate levels with objects then convert them to spawned objects so they can be moved back and forth between scenes?
User avatar
Tony Li
Posts: 21684
Joined: Thu Jul 18, 2013 1:27 pm

Re: Save/Load Items across scene

Post by Tony Li »

Hi,

Have you added a UIS Saver component to your player? This will save the UIS inventory. If you're also using UCC, make sure to UNtick the UCC Saver's Save Inventory checkbox, and also set all savers' keys to unique values on the player.

For level design, I think you can just drop regular item pickup prefabs into the scene and add Active Saver components. (Or add a Multi Active Saver to an empty GameObject, and assign multiple objects to it.) When the player picks up the item, its GameObject will be deactivated, so the Active Saver will record that it's inactive. When you return to the scene, the Active Saver will deactivate the GameObject. When you drop an item from your UIS inventory into the scene, this should be a separate GameObject that's different from the original item pickup object and has a SpawnedObject component.
kenlem
Posts: 25
Joined: Sun Aug 16, 2020 5:19 pm

Re: Save/Load Items across scene

Post by kenlem »

I have added a UIS Saver component on my player. I can see the item save information for that is in my save game data and items save and load to inventory properly so I think I'm all good there. I'm not using UCC (Ultimate Character Controller, I assume).

I'm working in VR so I'm not going to do it on grab. That would destroy the object you just grabbed in your hand which would be upsetting. I have 3d backpack that has events for adding and removing items. I think I'll try deactivated the object when it gets added to the backpack, then not actually add that object but a spawned copy of that object. That should do it.

Thanks so much for fast response.
User avatar
Tony Li
Posts: 21684
Joined: Thu Jul 18, 2013 1:27 pm

Re: Save/Load Items across scene

Post by Tony Li »

Glad to help! That sounds like a good plan.
kenlem
Posts: 25
Joined: Sun Aug 16, 2020 5:19 pm

Re: Save/Load Items across scene

Post by kenlem »

Ah, the key point in your reply is to have 2 versions of the object, one for use at design time and one to spawn. Was hoping to avoid that but if I can't, no big deal.
kenlem
Posts: 25
Joined: Sun Aug 16, 2020 5:19 pm

Re: Save/Load Items across scene

Post by kenlem »

OK. I have this working where I can pick up items, put them in my back pack, then move to a new room and drop them. Objects moved between rooms stay where they are left. All good.

I'm only using one version of the objects with a Spawned Object script on it. When I create a level at design time, I create an empty object with an Object Spawner script on it. This is a custom saver with a reference to the prefab to spawn at this location along with a hasMethodBeenCalled boolean flag. This spawns the a Spawned object the first time a scene is loaded and sets that flag to true. When I create a level, I'll just add spawners where ever I need inventory items. This isn't perfect but it works and I won't have that many props.

The only hacky thing I had to do was add code in OnLoadStart event where I destroy all the spawned objects. Without that, I found that if I save a level, stay in that level then load it, the existing spawned objects don't get destroyed and I end up with duplicate objects. I looks like the SpawnedObjectManager clears the list of spawned objects but doesn't destroy them.

It's a decent work around but visually spawned objects disappear from the scene before the scene change can fade to black. I moved the call to destroy the spawned objects to Standard Scene Transition Manager/OnTransitionEnd and now objects are all restore properly and objects no longer disappear when loading.

I tried overriding the ApplyData of the SpawnedObjectManager so that I could delete any existing spawned objects before create but I didn't have access to private fields I needed. I ended up creating my own SpawnedObjectManager but deleting objects in he ApplyData didn't work properly.

Any suggestions to do this better? I do have it working and if this is as good as it gets, then I can work with it. Just wondering if I'm overlooking something glaringly obvious. Thanks.
kenlem
Posts: 25
Joined: Sun Aug 16, 2020 5:19 pm

Re: Save/Load Items across scene

Post by kenlem »

Ah... I could make my own SpawnedObjectManager that looks to see if the object exists in the scene before it instantiates one. I bet that would work. Was thinking of doing a new one anyway to include velocity and angular velocity if a rigidbody exists.
User avatar
Tony Li
Posts: 21684
Joined: Thu Jul 18, 2013 1:27 pm

Re: Save/Load Items across scene

Post by Tony Li »

Good idea. It might be simpler to have your own SpawnedObjectManager track velocity rather than having to remember to put a separate custom velocity-saving saver component on each spawned object prefab.
Post Reply