Custom Remember Classes
What you’ll build
1) Create the class and inherit from SaveableComponent
SaveableComponent#if ARAWN_REMEMBERME && MEMORYPACK
using UnityEngine;
using MemoryPack;
using Arawn.CrystalSave.Runtime; // namespace where SaveableComponent lives
[AddComponentMenu("Crystal Save/Remember Components/Remember My Feature")]
[DisallowMultipleComponent]
// [RememberTarget(typeof(MyUnityComponent))] // optional: advertise your target type
// [RememberIcon("Some Unity Icon Name")] // optional: show a nicer icon
public sealed class RememberMyFeature : SaveableComponent
{
// (1) Toggle fields to control what you save
[Header("What to save")]
[SerializeField] private bool rememberEnabled = true;
[SerializeField] private bool rememberSomeValue = true;
// (2) Cache your target on Awake (and validate)
private MyUnityComponent target;
protected override void Awake()
{
base.Awake(); // IMPORTANT: ensures GameObject ID, component ID, registration, etc.
target = GetComponent<MyUnityComponent>();
if (target == null)
{
Logger.Log($"{nameof(RememberMyFeature)} requires {nameof(MyUnityComponent)} on '{gameObject.name}'.",
LogLevel.Error);
enabled = false; // mirror existing Remember components: disable if target missing
}
}
// (3) Serialize to bytes (compact & fast)
protected override byte[] SerializeComponentData()
{
if (target == null) return System.Array.Empty<byte>();
var payload = new Payload
{
Enabled = rememberEnabled ? target.enabled : default,
SomeValue = rememberSomeValue ? target.someValue : default, // example field
};
return Serializer.Serialize(payload); // SaveDataSerializer.Instance aliased as Serializer in base
}
// (4) Deserialize and apply safely
protected override void DeserializeComponentData(byte[] data)
{
if (data == null || data.Length == 0 || target == null) return;
try
{
var payload = Serializer.Deserialize<Payload>(data);
if (rememberEnabled) target.enabled = payload.Enabled;
if (rememberSomeValue) target.someValue = payload.SomeValue;
}
catch (System.Exception ex)
{
Logger.Log($"{nameof(RememberMyFeature)} deserialization error on '{gameObject.name}': {ex.Message}",
LogLevel.Error);
}
}
// (5) DTO you actually serialize
[MemoryPackable]
public partial class Payload
{
public bool Enabled;
public float SomeValue;
// parameterless ctor is fine; add [MemoryPackConstructor] if you define your own
}
}
#endif
Why these pieces matter
2) Store & validate your target in Awake
Awake3) Implement SerializeComponentData()
SerializeComponentData()4) Implement DeserializeComponentData(byte[] data)
DeserializeComponentData(byte[] data)5) Define your MemoryPack payload types
6) Build & use your component
Optional add‑ons you can copy from RememberCollider
RememberColliderCommon gotchas (and fixes)
Example: A minimal “Remember Light” (complete file)
How it flows (save ↔ load)
Checklist before you ship
Last updated