Create a Persistent Variables asset

A PersistentVariables asset holds a list of named values that the package saves and loads for you. To create one, select Create > Persistent Asset > Persistent Variables in the Project window.

A row holds any of over 40 types, including any enum, Unity's serializable structs, a project asset, and lists and maps of those.

Persistent Variables inspector
Note: Renaming a variable is safe: components stay wired and saves still load into it.

Variable components

Three components connect a variable to the rest of your scene:

  • Variable Binder keeps a variable in sync with a target member.
  • Variable Listener raises a UnityEvent when the variable changes.
  • Variable Setter writes a new value into the variable from a UnityEvent.

To add one, drag a variable by the handle at the left of its row onto a GameObject, then select which of the three components to add.

Dragging a variable onto a GameObject
Variable components in the inspector

Save and load from the Inspector

Two components put saving and loading on your own UI:

  • Persistence Operation Control runs any operation, slots included.
  • Persistence Operation Listener raises every event around an operation, plus ready, busy and the shutdown drain.
Wiring Save to a button OnClick
Warning: Put a Listener on a parent of any panel it switches off, because a disabled component stops listening.

Build a save menu

GameObject > Persistent Asset adds ready-made controls, each wired to the action it names: Save, Load, Continue, New Game and Quick Save buttons, a Save Menu and a Loading Spinner, all in uGUI; a Conflict Prompt and a Drain Display, each in an IMGUI and a uGUI version; and the Persistence Debug Overlay, in IMGUI. Assign your asset on the ones that act on it.

IMGUI needs no canvas but ignores gamepad input. uGUI builds on a canvas, takes your UI's style and accepts a gamepad.

Note: Place the Drain Display in the scene the game quits from, or in one that stays loaded.

The same menu holds a Save Menu, which lists one row per slot. To build one:

  1. Create the registry. Select Create > Persistent Asset > Variables Slot Registry, point it at your asset, and give it its own manager.
  2. Choose what a row shows. Add the variable names to Captured Variables, and set Capture From if you want a thumbnail.
  3. Build the menu. Select GameObject > Persistent Asset > Save Menu. Assign the registry on the Slot List and on the footer buttons, give each button its Target Object, and put the Slot List Row Template prefab in the Slot List's Row Prefab field.

Persist input bindings and a locale

Two optional modules add an Input Binding and a Locale Identifier variable type, each with a static helper. A rebind screen and a language selector need code:

variables.ApplyBinding("Jump", jumpAction);        // restore on startup
variables.RebindAndStore("Jump", jumpAction);      // run a remap screen, then store

variables.ApplyLocale("Language");                 // restore on startup
variables.SelectLocale("Language", new("fr"));     // pick one from a dropdown
Note: The locale helpers need Unity Localization initialized first.
Note: RebindAndStore returns a RebindingOperation. Cancel it in OnDisable.

Reference a variable from a script

To read and write a variable's value from code, serialize a variable reference field, then drag a variable onto it:

[SerializeField] VariableValueRef<int> coins;             // assigned in the inspector
[SerializeField] VariableListRef<string> unlockedSkins;   // assigned in the inspector

coins.Value -= price;
unlockedSkins.List.Add("gold");
A variable reference field in the inspector, a variable assigned to it

To add variable types, conversions and widgets of your own, refer to Add your own variable types.

Store values under keys of your own

Set creates a variable on the spot, under a key you choose:

variables.Set("gold", 120);
int gold = variables.Get("gold", 0);                 // the fallback stands in when missing

VariableList<string> inventory = variables.GetList<string>("inventory");
inventory.Add("sword");

The key is what identifies the variable, so writing under a new key creates another variable rather than renaming the first. Remove deletes the one you no longer want.

A variable authored in the Inspector window takes priority over a runtime one of the same key, from the next load on.

Note: Don't cache a list or a map. Fetch it again each time you need it, or in OnReloaded.