Saving only certain Components, custom
Posted: Tue May 30, 2023 10:56 pm
I'm trying to get ES3 to save a list of objects that
- have a reference to the prefab that instantiated them (using AssetReference to point to the prefab)
- have a list of components that need to be saved (only certain components have data to persist)
I've tried a number of different methods and nothing has worked so far.
Any object that I want to save has a SaveObject component attached. My top-level Save method collects all such objects in the scene and saves them. Here is my first attempt:
My Save method:
and SaveObject looks like:
However, when I did it this way, all the Components were saved by reference and none of their runtime data was saved, and their custom ES3Type Writers were never called. I tried using `memberReferenceMode = ES3.ReferenceMode.ByRefAndValue`, but this didn't work at all. It added a host of junk to the save file, and loading it back threw a bunch of errors about missing components.
Here is attempt #2. Rather than saving a custom Serialized object, I tried passing the list of SaveObjects directly to ES3.Save:
additionally, I tried using an ES3AutoSave component on each object with a SaveObject component, to list the components that should be saved.
I think I then had to select all such prefabs and choose "Enable Easy Save for Prefab". It gave me an error that AssetReference was unsupported, so I created a custom ES3Type for SaveObject. No errors now, but none of the components I added to ES3AutoSave appeared in the save data.
I'm out of ideas at this point. Any help would be much appreciated.
- have a reference to the prefab that instantiated them (using AssetReference to point to the prefab)
- have a list of components that need to be saved (only certain components have data to persist)
I've tried a number of different methods and nothing has worked so far.
Any object that I want to save has a SaveObject component attached. My top-level Save method collects all such objects in the scene and saves them. Here is my first attempt:
My Save method:
Code: Select all
data.Entities = UnityEngine.Object.FindObjectsOfType<SaveObject>().Select(b => b.Save()).ToList();
ES3.Save("game", data);
Code: Select all
public class SaveObject : MonoBehaviour {
public AssetReference Asset;
List<Component> Saveables = new();
public ILoadableObject Save() {
return new Serialized {
AssetGUID = Asset.AssetGUID,
Position = transform.position,
Rotation = transform.rotation,
Components = Saveables.ToArray()
};
}
class Serialized : ILoadableObject {
public string AssetGUID;
public Vector3 Position;
public Quaternion Rotation;
public Component[] Components;
public void Load() {
var asset = new AssetReference(AssetGUID);
asset.InstantiateAsync(Position, Rotation).WaitForCompletion();
}
}
public void RegisterSaveable(Component component) {
Saveables.Add((Component)component);
}
}
Here is attempt #2. Rather than saving a custom Serialized object, I tried passing the list of SaveObjects directly to ES3.Save:
Code: Select all
data.Entities = UnityEngine.Object.FindObjectsOfType<SaveObject>().ToList();
ES3.Save("game", data, settings);
Code: Select all
public class SaveObject : MonoBehaviour {
public AssetReference Asset;
List<Component> Saveables = new();
public void RegisterSaveable(Component component) {
GetComponent<ES3AutoSave>().componentsToSave.Add(component);
}
void Start() {
GetComponent<ES3AutoSave>().componentsToSave.Add(this);
GetComponent<ES3AutoSave>().componentsToSave.Add(transform);
}
}
I'm out of ideas at this point. Any help would be much appreciated.