Prefabs

Discussion and help for Easy Save 3
Post Reply
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Prefabs

Post by Notso »

So the issue Iam struggling with is saving loading prefabs.
Mine are hand placed in the scene but also instantiated from inventory when player drops them.
Some are deactivated in the scene when player is not in range (like most other objects to save on overhead)

How would I go about loading and destroying the objects that WERE there but had been picked up?
I added to my objects onawake they would add themselves to a list. And when picked up they would
remove themselves from that list.
(When dropped again they would be added to the list again AND be where I put them, but the original prefabs are still there as well and can't figure out how to remove them)
On my collectible item:

Code: Select all

private void Awake()
    {
        NotsoSave.prefabInstances.Add(this.gameObject);
    }
Then in the method on that same script:

Code: Select all

public override void Activate(CharacterManager characterManager)
    {
        if (_inventory != null)
        {
            if (_inventory.AddItem(this))
            {
                if (ApplicationManager.instance && _setOnCollect.Count>0)
                {
                    foreach( GameState state in _setOnCollect)
                    {
                        ApplicationManager.instance.SetGameState(state.Key, state.Value);
                    }
                }
                NotsoSave.prefabInstances.Remove(this.gameObject);
                Destroy(gameObject);
            }
        }
    }

EDIT:
I found your SaveDestroyed script, and this is almost working. The issue I have is once I drop the item from the backpack, it destroys because the GUID is on the list when start method runs. It assigns the same GUID to the instantiated prefab.
But then I though what if instead of onstart I just use destroy and add it to a string list, then save that list and on start iterate through the list and destroy the objects..didn't go as planned either...
(Hope it is clear, I have the prefabs saving and loading fine...the issue is on loading a game how to identify the original scene items that were picked up (destroyed) and no longer exist and (re)destroy them so the newly dropped GO are the ones left in scene)
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Prefabs

Post by Joel »

Hi there,

The SaveDestroyed script won't work for prefabs instantiated at runtime because it won't be possible to generate a persistent GUID for them which is unique to each prefab instance.

Generally the List of prefabs that is in your save data should only contain prefabs which haven't been destroyed. If you destroy a prefab, you will also need to remove the prefab from this list and re-save it (I don't see anywhere where you're resaving it in your code). Then when you load the prefabs list, only prefabs which haven't been destroyed will be instantiated.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Re: Prefabs

Post by Notso »

Right, but the ones that are destroyed are still there when you load the game because they are hand placed, I need a way to identify them to re-destroy them. My prefabs are not instantiated. Only the ones dropped from inventory.
Example, I have 2 prefabs in the scene. I pick one up (it gets destroyed). I save the list. 1 prefab is on it. I drop the prefab somewhere else, save the list, now 2 prefabs are in the list. On Load I now have 3 prefabs because the hand placed one is still there in the scene. I need a way to identify between the 2 same prefabs so I can destroy the original one.
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Prefabs

Post by Joel »

Hi there,

If it's hand-placed then it's no longer a runtime prefab instance and will count as a scene object. For these objects you can use the SaveDestroyed script.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Re: Prefabs

Post by Notso »

But I can't. There are more than 1 of the same placed item in the scene.
3 cans of food in the scene, these cans will have the same GUID since they use the same prefab. They pick up 1, it adds that guid to the destroy save file, on load it will delete all of them since they have the same GUID.
Or 10 boxes of ammo, they pick 1 up it will remove all of them on load because of the same GUID. Whether hand placed or instantiated by being dropped.
I need each item to have a unique identifier even if from the same prefab. I did just do a test, and if I tried to drop the item I just picked up, it destroyed it the moment i tried to drop it because it was on the list.
Ultimately I would like to be able to use something like your savedestroy but in a list then on load it iterates through and destroys them instead of on start. But as I mention, 10 objects from the same prefab have the same GUID so all 10 get destroyed. Unless I am doing something wrong.
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Prefabs

Post by Joel »

Hi there,
Notso wrote: Mon Dec 18, 2023 3:05 pm But I can't. There are more than 1 of the same placed item in the scene.
You place the script on the instance in the scene, not on your prefab. This will ensure that each one has a unique ID.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Re: Prefabs

Post by Notso »

I can do that, but then how do I go about instantiating them? add something like add component so the new ones now get a new ID?

OK so I tested and I can pick up and drop and it seems to work (not a fan of saving as soon as they pick up).
However the newly instantiated ones will not have a GUID now. Should I do something like addcomponent when instantiated and add the savedestroy on it? Or is there another way to do it?
OK, I think I got it mostly. Now to tell save/destroy to only run when I actually want to use a save game to load.
Last edited by Notso on Tue Dec 19, 2023 5:44 pm, edited 1 time in total.
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Prefabs

Post by Joel »

Hi there,

You don't use the SaveDestroyed script on the instantiated prefabs, only on the objects that you've added to the scene prior to runtime. With prefabs instantiated at runtime you just need to ensure that you remove them from the array of prefab instances and resave this array when destroying a runtime prefab instance to ensure that it's also removed from your save data.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Re: Prefabs

Post by Notso »

OK, so you think this is good then?
(all prefabs are es3prefabs)
Already on scene objects only when it loads I have the savedestroy.
For the ones that get instantiated I have a method that adds them to the prefabinstantiate list. Once I pick it up, I remove it from the list and destroy it from the scene.
This is on my collectableitem script, sends a call to the save script list:

Code: Select all

private void Awake()
    {
        NotsoSave.prefabInstances.Add(gameObject);
    }
Then when picked up

Code: Select all

if (_inventory.AddItem(this))
            {
                if (ApplicationManager.instance && _setOnCollect.Count>0)
                {
                    foreach( GameState state in _setOnCollect)
                    {
                        ApplicationManager.instance.SetGameState(state.Key, state.Value);
                    }
                }
                NotsoSave.prefabInstances.Remove(gameObject);
                Destroy(gameObject);
            }
On my savescript
Save:

Code: Select all

ES3.Save("prefabInstances", prefabInstances);
Load:

Code: Select all

prefabInstances = ES3.Load("prefabInstances", new List<GameObject>());
Even though it is marked as an es3 prefab, can wE still use es3gameobject to select what to save? Or can I use [ES3NonSerializable] in front of some things?
Do I need to clear the lists before saving again or is it OK to just keep hitting save?
I ran into a weird issue and just after i got it working!
But that is a game issue. Appears as if it doesn't like being saved near walls?? I manually moved player forward and got all kybd control back, but it even stopped TAB and ESC from working in game..(This is not an ES3 issue, I know)
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Prefabs

Post by Joel »

Hi there,
OK, so you think this is good then?
That looks fine to me.
Even though it is marked as an es3 prefab, can wE still use es3gameobject to select what to save?
Correct, ES3Prefab and ES3GameObject work together.

Hope you get your game issue resolved!

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Post Reply