Messing up references when regenerating prefabs

Discussion and help for Easy Save 3
RequiemOfTheSun
Posts: 14
Joined: Tue Dec 29, 2020 4:14 am

Messing up references when regenerating prefabs

Post by RequiemOfTheSun »

I've dug myself into a hole and could use advice on how I should be thinking about saving and loading for nested game objects with references to other game objects.

For context I generate my game world as a nested structure of game objects defining orbiting bodies in a solar system. Star -> Planet -> Moon.

How I've set things up right now I've disabled child objects from saving, it just seemed to capture way too much junk that I can get back just by loading a prefab. So I've got my whole solar system built out in a single prefab, I instantiate a copy of that, destroying the previous one to clear up items that weren't saved. Then I use ES3.LoadInto("solarSystem", newSolarSystem.gameObject) to try to restore the references.

Items then are nested onto whichever body they are closest to. The Items I'm instantiating from prefabs and have them configured through AutoSave/Prefab where I manually call the AutoSaveMgr to load them after I've reloaded the solar system. I figured if I first manually load the world hierarchy then I can call AutoSaveMgr and it should be able to parent the items to their saved transform.parents.

I'm trying to get just that saving and loading and haven't had much luck. The initial difficulty is I figured the best way to reload would be to destroy the entire solar system of game objects and reload it fresh each time to clean up any objects that aren't in the save file. I believe this means I'm losing the references that saved items are saving with their transform parent which is why they load at the root of the hierarchy instead of as children of the orbital bodies.

However I now have confused myself pretty good and I'm wondering if maybe I'm supposed to be manually handling references in the reference manager or something.

So I figured I'd ask what's a good pattern to follow that makes it easy to save nested game objects?

Do I need to be careful about the order I load objects so their references exist when they are loaded?

I'm willing to refactor how I'm building things if it makes any of this easier.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Messing up references when regenerating prefabs

Post by Joel »

Hi there,

The order in which you load references is important as you can't load a reference which doesn't exist. In your case it would be worth loading your transform.parent fields separately, after you've loaded the objects themselves.

For example, let's say that you have a top-level GameObject called 'topGO' which is the parent to all of your GameObjects. You could do something like this to store the parent reference for each of your child GameObjects:

Code: Select all

var transforms = topGO.GetComponentsInChildren<Transform>();
// The key of this Dictionary is the reference ID of the Transform,
// and the value is the reference ID of it's parent (or -1 if it has no parent)
var parents = new Dictionary<long, long>();
foreach(var transform in transforms)
	parents.Add(ES3ReferenceMgr.Get( transform ), ES3ReferenceMgr.Get( transform.parent ));
ES3.Save("parents", parents);
And then after you load everything else in your scene, you can do something like the following to restore the parent/child relationship.

Code: Select all

var parents = ES3.Load<Dictionary<long, long>>("parents");
foreach(var kvp in parents)
{
	long transformID = kvp.Key;
	long parentID = kvp.Value;
	
	if(transformID == -1)
		continue;
	var transform = (Transform)ES3ReferenceMgr.Current.Get(transformID);
	
	if(parentID == -1)
		transform.parent = null;
	else
		transform.parent = (Transform)ES3ReferenceMgr.Current.Get(parentID);
	
}
This is just provided as an example so you might need to take a slightly different approach to suit your project. However, this should give you the general idea of what you could do.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
RequiemOfTheSun
Posts: 14
Joined: Tue Dec 29, 2020 4:14 am

Re: Messing up references when regenerating prefabs

Post by RequiemOfTheSun »

That sounds promising and helps me understand the Reference manager a bit better thanks!

Is there a difference letting the AutoSave manager store references as opposed to grabbing the root game object and saving it myself? I'm saving the same solar system prefab through both right now to compare the output and I'm seeing the AutoSave managed version has the ES3 Refs that I'm looking for for a child game object, but the version of the solar system I saved manually has different ES3 reference ids. When I try to grab the ref myself through the manager I get back a -1.

I've configured the Solar System prefab to save off the transforms I use as parents. For editor settings I have Auto Update References, Use Global References and Add all prefabs to manager checked.

It looks like the reference manager isn't keeping up? If I manually refresh while live it it get's another 60k references and now I get back an id.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Messing up references when regenerating prefabs

Post by Joel »

Hi there,
Is there a difference letting the AutoSave manager store references as opposed to grabbing the root game object and saving it myself?
It shouldn't make any difference as both call ES3.Save(key, yourRootGameObject) underneath.
It looks like the reference manager isn't keeping up? If I manually refresh while live it it get's another 60k references and now I get back an id.
The reference manager will only have references to things which are not instantiated at runtime. Things which are instantiated at runtime will only be added to the reference manager if you attempt to save it, or it's been loaded by Easy Save.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
RequiemOfTheSun
Posts: 14
Joined: Tue Dec 29, 2020 4:14 am

Re: Messing up references when regenerating prefabs

Post by RequiemOfTheSun »

Things are progressing well, thank you for your help!

Is there a reason why LoadInto for prefabs doesn't apply references? I see that ES3Prefab.ApplyReferences is only called in the method ES3Type_ES3PrefabInternal.Read which isn't called when I use LoadInto instead of Load.

I can't be positive without digging into this deeper but this seems to be the source of a lot of my problems. I instantiate prefabs through Forge multiplayer plugin which means I need to let that instantiate and then use LoadInto to recover my data. When I do this other objects references to children within the prefab don't work like they do when I use Load.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Messing up references when regenerating prefabs

Post by Joel »

Hi there,

If you're using ES3.LoadInto then you're telling Easy Save that you want to use the references that you've provided. ES3Prefab.ApplyReferences is for prefabs instantiated internally by Easy Save.

Currently if you want Easy Save to manage all of your references, you would need to use ES3.Load to allow Easy Save to create an instance, rather than creating your own instance.

If you private message me your invoice number, I can send over an update which applies the references when using ES3.LoadInto too, though note that this won't be thoroughly tested at our end so I'm unsure if there would be any intended consequences to doing this.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
RequiemOfTheSun
Posts: 14
Joined: Tue Dec 29, 2020 4:14 am

Re: Messing up references when regenerating prefabs

Post by RequiemOfTheSun »

Hey Joel,

Thanks for the LoadInto scripts, my multiplayer was already broken so I've moved to Load for now just to keep things as "default" as possible for debugging.

New problem I've got, whenever I make a change to a prefab like adding or removing a component (one that is not part of the saved prefab data). All my existing saves break. I'm trying to debug and read through the save files to figure out what the issue is but so far I'm still stuck. The prefab ID is still the same, the prefabs are always loaded at runtime, both initially and a loaded version.

Any thoughts on what might be going wrong here?
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Messing up references when regenerating prefabs

Post by Joel »

Hi there,

Unfortunately I wouldn't be able to tell what's happening from what you've said. Please could you private message me a new project with a basic scene which replicates it?

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
RequiemOfTheSun
Posts: 14
Joined: Tue Dec 29, 2020 4:14 am

Re: Messing up references when regenerating prefabs

Post by RequiemOfTheSun »

After a lot of head scratching I've finally found in another thread where you need to copy/paste the ReferenceManager between scenes. My game requires going through a main menu. Anyway with that copy/pasted manager the parenting transforms issue doesn't seem to be a problem anymore as the parent will appear first in the hierarchy and load before the child expecting it is loaded.

Did I miss where this copy/paste solution is called out in your guides? If not I'd request you add a giant banner or detect this issue and raise it as warnings lol. It's quite hard to trace this from the effects it causes.

I still have issues with adding a component to a prefab causes the prefabs local child transform references to not be found for children trying to parent to them. I've tried to pair down a project to the essentials but a fresh project won't replicate the issue. I'll keep digging into this.
Last edited by RequiemOfTheSun on Tue Jan 19, 2021 6:42 pm, edited 1 time in total.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Messing up references when regenerating prefabs

Post by Joel »

Hi there,

Copying and pasting the reference manager was only necessary in earlier versions of Easy Save 3 where we didn't have a global reference manager. Just to check, do you have global references disabled in the Easy Save settings?

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