Save custom classes with Remember CustomComponent
1 What the component does
Created for non-coding Game Designers, RememberCustomComponents is a generic SaveableComponent that scans your GameObject for custom MonoBehaviours (i.e. anything not part of UnityEngine or Crystal Save’s own helpers) and captures a snapshot of their serializable fields at save-time, then re-applies those values on load, adding missing components if necessary.

2 Requirements
Crystal Save Core
Crystal Save Settings present
3 Installation & first-time setup
Select the GameObject whose custom components you wish to persist.
Add Component → Crystal Save / Remember Component
Add through the Remember Component the Remember Custom Component
Enter Play mode, exercise your custom component (modify its fields), then call:
SaveManager.Instance.Save(1);
SaveManager.Instance.Load(1, restoreLastActiveScene: true);
Or make use of Tools/Crystal Save/Runtime Debug/Manage Save Slots and click the save button and then the load button.
You should see your MonoBehaviour fields restored exactly as they were.
4 Inspector reference
[SerializeField, HideInInspector]
private SerializationMode mode = SerializationMode.AllCustomComponents;
// If SelectedComponents mode, you’ll see a mask-field for picking specific MonoBehaviours:
[SerializeField, HideInInspector]
private List<MonoBehaviour> components = new();
SerializationMode.AllCustomComponents (default): captures every custom MonoBehaviour on the GameObject.
SerializationMode.SelectedComponents: only snapshots the list you pick via the mask field.
5 How the save / load cycle works
On save,
SerializeComponentData()
callsGetTargets()
→ iterates each target component, builds aComponentSnapshot
of its fields, then serializes the list viaSaveDataSerializer
.On load,
DeserializeComponentData(byte[] data)
reconstructs eachComponentSnapshot
, locates or (AddComponent
) the target type, then reflects through each savedFieldSnapshot
, performing a safe conversion and setting the field viaFieldInfo.SetValue
6 Supported Types
Primitives:
int
,float
,double
,bool
,string
UnityEngine Objects:
GameObject
(by UniqueID),Transform
,Texture2D
,AudioClip
,AnimationClip
,Sprite
,Material
, etc.Structs:
Vector2
,Vector3
,Color
Collections: any
IList
→List<TypedObject>
, anyIDictionary
→Dictionary<TypedObject, TypedObject>
Enums
GameCreator types (if present) via conditional compilation wrappers
7 Limitations
Field-only
Only serializes fields—not C# properties or methods.
SerializeField/Public Only
Private fields must carry
[SerializeField]
; otherwise they’re ignored
Supported Types Only
If a field’s type isn’t in the
TypedObjectFactory
map (e.g. a custom class), it will be skipped with a warning. Complex nested or cyclic references aren’t handled.
Unity Object References
UnityEngine.Object
fields must be assigned in the Inspector; null references are silently skipped
Performance
Reflection has overhead—avoid huge collections or per-frame use. Best for occasional save/load cycles.
8 Extending the component
To handle extra data per component type:
Subclass
RememberCustomComponents
.Override
SerializeComponentData()
/DeserializeComponentData()
, callbase
, then append or process your extra fields.Register your subclass in the Composite (if using
RememberComposite
) or add it directly.
9 Troubleshooting & FAQ
Fields aren’t restored → check they’re public or marked
[SerializeField]
.“Unsupported field type…” warnings → inspect logs; unsupported types simply aren’t saved. Consider writing a custom
TypedObjectFactory
extension.Component not added on load → the
ComponentType
string must match an accessible type viaType.GetType(…)
; custom namespaces/assemblies must be resolvable.
You’re all set—hook your UI or gameplay code to SaveManager’s save/load calls, and RememberCustomComponents will travel with every slot, transparently preserving your custom MonoBehaviour state.
Last updated