Lifecycle

When Initialize, SetPayload, Enter, Exit and Dispose run.

StateFlow calls a fixed set of methods on every StateFlowComponent in a state, always in the same order. Knowing which ones run before a transition plays, and which wait for it to finish, tells you where each piece of set-up belongs.

The methods

MethodRunsUse it to
Initialize()Once, right after the state is spawnedCache components, hook up buttons, subscribe to services
SetPayload(T)After Initialize, only if the transition carried a payload of a type the state acceptsStore and display the payload
LateInitialize()After the payload is setSet-up that needs both the UI and the payload
Enter()When the state becomes the active one, after the transition into itStart animations and timers, refresh values that may have changed
TransitionFinished()Right after Enter, once the transition has completedWork that should wait until nothing is moving
Exit()When another state becomes active: this one is being left, or a higher layer opened on topPause what Enter started
Dispose()Just before the state is destroyedRelease what Initialize acquired

The order, case by case

These logs come from the 05 Lifecycle and Observer sample, which logs every call:

Moving to another screen (with a payload)

Log
Observer  Alpha → Beta  (Hello from Alpha)
AlphaScreen.Exit
AlphaScreen.Dispose
BetaScreen.Initialize
BetaScreen.SetPayload("Hello from Alpha")
BetaScreen.LateInitialize
transition starts
transition ends
BetaScreen.Enter
BetaScreen.TransitionFinished

Alpha is exited and disposed as soon as the transition starts, but it stays on screen until the transition ends, so it can still be animated out. It is destroyed after that.

Opening a popup on top

Log
Observer  Alpha → Gamma
AlphaScreen.Exit
GammaPopup.Initialize
GammaPopup.LateInitialize
transition starts
transition ends
GammaPopup.Enter
GammaPopup.TransitionFinished

Alpha gets Exit but not Dispose: it is still open underneath.

Closing the popup

Log
Observer  Gamma → Alpha
GammaPopup.Exit
GammaPopup.Dispose
AlphaScreen.Enter
AlphaScreen.TransitionFinished

Alpha is not initialized again. It gets Enter, so refresh anything that the popup might have changed (a balance, a settings value) in Enter, not in Initialize.

The entry state

The entry state runs Initialize, LateInitialize, Enter and TransitionFinished in a row as soon as it has loaded. With Resources loading that happens during the StateFlow Manager's Awake. There is nothing to transition from.

Leaving from Initialize

Enter and Exit always alternate, and a state never gets Exit before it has entered. If a state opens a popup from its own Initialize or LateInitialize, it doesn't enter until that popup closes. If it is replaced that early, it never enters at all, and goes straight to Dispose.

Play mode
The Gamma popup open over Alpha, with a log panel on the right listing lifecycle calls and observer notifications with frame numbers.
The 05 Lifecycle and Observer sample logs every call next to the frame it happened in.
Try it

Import Feature Samples from the Package Manager and open 05 Lifecycle and Observer/05 Lifecycle and Observer.unity. About the samples

Child components

Every StateFlowComponent in the state's hierarchy receives the lifecycle calls, root first. Content you spawn at runtime with StateFlowSpawner gets its own lifecycle; see Spawned content.

Exceptions

An exception thrown from any lifecycle method except Initialize is logged, and the remaining components still receive their call, so one broken component can't stall the flow. Keep Initialize free of code that can throw.