Restore state of individual Object

This guide shows how to restore just one Prefab or GameObject with Crystal Save using the SaveManager API — without reloading your whole scene or touching anything else.


When to use this

  • “Reset puzzle” button for a specific object

  • Re-open a UI panel to its last state

  • Snap the player or an NPC back to a saved pose

  • Debugging: compare a live object against a prior save


What gets restored

For the chosen object Crystal Save reapplies:

  • Active state (SetActive)

  • Transform (position/rotation/scale)

  • Saved Rigidbody & Animator snapshots (if present)

  • All Remember/SaveableComponent data you attached

  • Runtime prefab modifications (name/tag/layer, mesh/material swaps, etc.)

Tip: Scene objects should have a Remember Component with the helpers you need (e.g., Transform). Runtime/spawned objects should use SaveablePrefab on the prefab asset.


Quick start: three common patterns

A) You already have the GameObject (restore from slot)

// Restore 'player' from slot 1 (async under the hood; fire-and-forget)
SaveManager.Instance.RestoreSingleGameObject(player, slotNumber: 1);

B) You only know its UniqueID (restore from slot)

// You can pass either a live UniqueID or the prefab asset ID
const string bossDoorID = "Door_BossRoom_003";
SaveManager.Instance.RestoreSingleGameObject(bossDoorID, slotNumber: 3);

C) Re‑apply from the currently loaded SaveData

If you already loaded a save (and have in‑memory SaveData), you can re-apply just one object:

// Instant “reset this object to the last loaded save”
SaveManager.Instance.RestoreSingleGameObject(puzzleGO);

Full API (what’s available)

1) Restore by GameObject

// Re-apply from the current SaveData already in memory:
void RestoreSingleGameObject(GameObject target);

// Re-apply from a specific SaveData blob (e.g., one you loaded earlier):
void RestoreSingleGameObject(GameObject target, SaveData data);

// Same as above, but lets you suppress the completion event:
void RestoreSingleGameObject(GameObject target, SaveData data, bool suppressEvent);

// Load slot N (with retries) and then restore the target:
void RestoreSingleGameObject(GameObject target, int slotNumber);

// Retry loop you can await (returns true on success):
Task<bool> RestoreSingleGameObjectWithRetryAsync(GameObject target, int slotNumber,
                                                 int maxRetries = 3, int retryDelayMs = 500);

2) Restore by UniqueID or Prefab Asset ID

// Use the live object if found by UniqueID; otherwise fall back:
// - if an instance of the prefab already exists, use it
// - else, find saved prefab data in the slot, instantiate just that one,
//   then apply its saved state.
void RestoreSingleGameObject(string uniqueOrPrefabId, SaveData data = null);

// Load slot N (awaitable variant available, see below)
void  RestoreSingleGameObject(string uniqueOrPrefabId, int slotNumber);
Task RestoreSingleGameObjectAsync(string uniqueOrPrefabId, int slotNumber);

You can pass either:

  • the instance UniqueID (scene object or prefab instance), or

  • the prefab asset ID (it will instantiate & restore a new instance if needed).


Examples you can copy‑paste

Restore a vendor chest UI from slot 2

[SerializeField] GameObject vendorPanel;

public void OnReopenVendor()
{
    SaveManager.Instance.RestoreSingleGameObject(vendorPanel, 2);
}

Reset only the moving platform to its saved pose

[SerializeField] GameObject movingPlatform;

// Uses the currently loaded SaveData (no slot IO)
public void OnResetPlatform()
{
    SaveManager.Instance.RestoreSingleGameObject(movingPlatform);
}

Restore by ID when you don’t hold a reference

// UniqueID printed in the UniqueID component / debug tools
const string checkpointId = "Checkpoint_A_01";
public void OnResetToCheckpoint() =>
    SaveManager.Instance.RestoreSingleGameObject(checkpointId, 1);

Await restoration with retry + custom policy

async void RestoreSafely(GameObject target, int slot)
{
    bool ok = await SaveManager.Instance
        .RestoreSingleGameObjectWithRetryAsync(target, slot, maxRetries: 5, retryDelayMs: 300);
    if (!ok) Debug.LogWarning($"Could not restore {target.name} from slot {slot}");
}

Restoring destroyed objects (respawn)

If the object was removed (e.g., breakable crate), use the destroyed-object helpers:

// Respawn a single destroyed object by UniqueID
SaveManager.Instance.RestoreDestroyedGameObject("Crate_TutorialRoom_05");

// Respawn *all* destroyed objects that still have prefab mappings
SaveManager.Instance.RestoreAllDestroyedGameObjects();

Under the hood, Crystal Save looks up the original prefab, instantiates it, applies component data captured at destruction, and re-registers it for future saves.


Quality-of-life helpers (most recent slot)

Need “restore from the latest save”? Use the extensions:

// Restore one object from the most recent slot
await SaveManager.Instance.RestoreSingleGameObjectsFromMostRecentSlotAsync(player);

// Restore a batch (fires OnSingleGameObjectRestored for each by default)
await SaveManager.Instance.RestoreSingleGameObjectsFromMostRecentSlotAsync(
    new[] { enemyA, enemyB, bossDoor }, fireEventForEach: true);

Events & hooks

  • SaveManager.OnSingleGameObjectRestored(GameObject go) Fired after a targeted restore completes. Great for VFX, SFX, or UI updates.

Example:

void OnEnable()
{
    SaveManager.OnSingleGameObjectRestored += HandleRestored;
}
void OnDisable()
{
    SaveManager.OnSingleGameObjectRestored -= HandleRestored;
}
void HandleRestored(GameObject go)
{
    if (go == player) PlaySnapBackEffect();
}

Troubleshooting & best practices

  • UniqueID is required. Scene objects should have a UniqueID (via Remember Component). Prefabs should use SaveablePrefab (and be instantiated via your usual flow — using SaveablePrefabFactory is recommended for runtime spawns).

  • Object isn’t found by ID? If no live object exists and the ID is a prefab asset ID, the API will try to instantiate it from the saved slot. If it’s an instance ID that no longer exists and no prefab data is present, you’ll see a warning.

  • Destroyed vs. targeted restore. Use targeted restore for objects that still exist; use destroyed-object restore to respawn things you removed.

  • Cloud enabled? The slot read happens through your configured backend (Unity Cloud Save, Supabase, Firebase, MySQL) or the local mirror — no extra work needed on your side.


Minimal checklist

  • The object has Remember/SaveableComponents for the data you need.

  • Scene object has a UniqueID; runtime prefabs have SaveablePrefab.

  • You saved at least once to the slot you’re restoring from.

  • For ID‑based restore, you’re using the correct UniqueID or Prefab Asset ID.

  • If the object was destroyed, use RestoreDestroyedGameObject.


FAQ

Q: Will this block my main thread? A: Slot I/O is performed asynchronously; the actual re‑apply happens on the main thread and is typically a single frame.

Q: Can I restore multiple things at once? A: Yes, just call RestoreSingleGameObject for each object (or use the “most recent slot” extension that accepts a list).

Last updated