How the framework thinks
Five ideas explain everything: element scenes, states, the stack, context and shared elements.
Vocabulary
| Term | Meaning |
|---|---|
| Element scene | A Unity scene with one root object <Name>Root holding a UiElement. The unit of loading. |
| UiElement | A MonoBehaviour that receives data in Populate(object context) and owns its show / hide animation presets. |
| State | A named set of element scenes, identified by a state key, e.g. StoreUiState. |
| Context | The object passed to ShowState, forwarded unchanged to every element of the state. Usually a UiPopulationParams subclass. |
| Shared element | A scene used by consecutive states. It stays loaded, is re-populated, and is not animated. |
An element's lifecycle
The state stack
Non-additive (the default) replaces the whole stack: the new state animates in while every state on the stack animates out, then the old states are released.
Additive pushes on top, for popups and overlays. The states below stay loaded and visible.
HideUI() pops the top state, plays its hide animations and releases its scenes.
ResetUIAsync() hides and unloads everything.
Shared elements and reference counting
Scenes are identified by their Addressables GUID and counted per state on the stack. The new state's scenes are counted before the old ones are released, so a scene used by both never unloads and reloads in between. A scene unloads only when its count reaches zero.
State classes are type markers
ShowState<StoreUiState>() finds the state whose key equals the class name. The runtime builds the state from the config, so code inside a UiState subclass never runs: keep behaviour in your elements. For keys without a class, use ShowStateByKey("StoreUiState").
The element scene contract
Animation targets the one object under the Canvas, so every element scene has the same shape. The Elements tab checks it and fixes it in one click.
Good to know
One call at a time
Overlapping ShowState / HideUI calls are not queued for you. Await each call, or route navigation through one place that queues them (the showcase's ShowcaseNavigator does).
HideUI and shared elements
HideUI doesn't skip elements shared with the state underneath, so keep popups to their own scenes.
Initialization
IsInitialized is true as soon as the manager exists, before the config has loaded. Await InitializeAsync() before showing states.
No data binding
The framework hands each element its context. Updating what is already on screen (a coin counter) is your code, for example events on your data.