Stack-based screen navigation for Unity UI Toolkit. Push, pop, replace screens with animated transitions, lifecycle hooks, back-stack management, and input blocking. Full source. Zero dependencies.Unity 6 UI Toolkit ships with no concept of screens, pages, or navigation. You're left manually showing and hiding VisualElements, writing your own back-stack, and praying your transitions don't double-fire when two navigations land in the same frame.This asset is the missing navigation layer. Stack-based push/pop/replace, six async lifecycle hooks per screen, five built-in transitions, automatic back-button handling, and deep-link navigation with synthetic back-stacks — all built on UI Toolkit's existing primitives, no separate canvas, no GameObject-per-screen.One-line navigation.```await Manager.PushAsync("Gameplay");await Manager.PopAsync();await Manager.ReplaceAsync("MainMenu");await Manager.PopToAsync("MainMenu");await Manager.NavigateToAsync("ItemDetail", new[] { "MainMenu", "Shop" });```Every navigation call is async, returns a `NavigationResult` you can inspect, and respects the configured transition. Calls made during an active transition queue up and run sequentially — no double-tap navigation bugs, no race conditions in your menus.Six async lifecycle hooks per screen.`OnScreenCreated` (bind UXML once), `OnScreenEnter` (start animations, fetch data), `OnScreenPause` (a screen was pushed on top), `OnScreenResume` (returned to foreground), `OnScreenExit` (about to leave the stack), `OnScreenDestroy` (final cleanup). Every async hook receives a `CancellationToken` and is protected by a configurable timeout — no hung lifecycle hook can block navigation indefinitely.Five built-in transitions, customizable per screen.Fade, Slide (left / right / up / down with auto-reverse on pop), Scale, Crossfade, and None ship out of the box, driven by USS transition properties for GPU-accelerated smoothness. Duration and easing are per-screen in the Inspector; set a screen's transition to "Inherited" to fall through to the manager's default. Want something custom? Implement `IScreenTransition` or subclass `ScreenTransitionBase` and the custom transition type shows up in the Inspector dropdown automatically.Back-button handling that just works.UI Toolkit's `NavigationCancelEvent` maps Escape (desktop), the Android hardware back button, and gamepad B / Circle for you. Override `OnBackPressed()` on any screen and return `true` to consume the event — perfect for a "discard changes?" confirmation. The `OnBackAtRoot` event fires when the user presses back at the root screen, ready to be wired to a quit dialog. A transparent overlay automatically blocks pointer and navigation input during transitions, so nothing lands mid-animation.Deep-link navigation with synthetic back-stacks.Launch directly into any screen from a push notification, a daily-challenge URL, or startup logic. `NavigateToAsync("ItemDetail", new[] { "MainMenu", "Shop" })` builds the intermediate stack silently — the user lands on ItemDetail with MainMenu and Shop already behind them, so pressing Back walks them through the path as if they had navigated there manually. Pass typed data along the way via `NavigationOptions.Data` and read it on the other side with `TryGetNavigationData()`.History-aware screens and three preload modes.Per-screen `BackStackBehavior` controls how each screen participates in back navigation: `Standard` (normal), `SkipOnBack` (in the stack but skipped on back — loading screens), or `NoHistory` (never added — splash screens, game-over screens). Per-screen `ScreenLoadMode` controls when each screen is instantiated: `Lazy` (on first navigation), `Preload` (at startup, with `OnScreenCreated` fired immediately for binding), or `OnDemand` (via explicit `PreloadScreenAsync` call).Custom inspectors with live debugging.The custom `ScreenManager` inspector shows the active screen, the full stack from bottom to top, transitioning status, and manual push / pop / replace controls while the game is running. The `ScreenRegistry` inspector validates every entry with a one-click "Validate All" button and surfaces inline warnings for missing UXML assets, duplicate IDs, or unknown screen types.Two demo scenes included.**GameDemo** — a five-screen game flow: a Main Menu with push navigation and a deep-link trigger, a Settings screen with toggle / slider controls and `SkipOnBack` behavior, a Gameplay HUD with a coin-catching mini-game (falling coins, click-to-score, health bar, game-over detection), a Pause Menu overlay using the Scale transition, and a Game Over screen with Replay (`ReplaceAsync`) and Main Menu (`PopToRootAsync`) buttons using `NoHistory`. **MacroTrackerDemo** — a nutrition-tracker flow showing realistic data-driven screen navigation with typed data passing between screens. Both demos ship with controllers, UXML, USS, and configured panel settings; no external art dependencies, only built-in UI Toolkit styling.Plays well with the rest of the UI Toolkit Components suite.Open `Tools > KrookedLilly > Screen Manager Setup` to see every sibling that consumes from Screen Manager — Focus & Navigation, Modal & Notifications, Theme Switcher, Form Validation, Data Binding, ECS Bridge. Tick a row to enable that sibling's integration; each one ships disabled by default so your project never picks up code from siblings you do not enable.**With UI Toolkit: Tween Engine** — open `Tools > KrookedLilly > Tween Engine Setup` and enable the Screen Manager row. Four tween-driven `IScreenTransition` implementations (Fade, Slide, Scale, Crossfade) snap into Screen Manager's navigation system through `TransitionProvider`. Pick one per screen in the Inspector or set it as the default; the tween runtime takes over from the built-in CSS transitions. Without the toggle, Screen Manager continues to use its built-in CSS transitions.Works on every platform.Render-pipeline agnostic — runs under URP, HDRP, and the Built-in pipeline. Runs under Mono and IL2CPP scripting backends. Uses the standard Unity AOT path that ships on iOS, Android, WebGL, and consoles.Full C# source, no DLLs.XML documentation on every public API. Zero external dependencies — only the `com.unity.modules.uielements` module is required.Navigation API- `PushAsync(screenId, options = default)` — push a new screen on top of the stack- `PopAsync(options = default)` — return to the previous screen- `ReplaceAsync(screenId, options = default)` — swap the current screen without growing the stack- `PopToAsync(screenId, options = default)` — pop multiple screens at once to reach a target- `PopToRootAsync(options = default)` — return to the first screen on the stack- `NavigateToAsync(targetScreenId, stackPath, options = default)` — deep-link with synthetic back-stack construction- `PreloadScreenAsync(screenId)` — instantiate without navigating, useful for `ScreenLoadMode.OnDemand`- Every method is async and returns `NavigationResult` with `Success`, `FailureReason`, and `ErrorMessage` for explicit inspection- Calls made during an active transition queue up and run sequentially- `NavigationOptions` carries per-call transition overrides, payload data, and back-stack behaviorLifecycle- `OnScreenCreated(VisualElement root)` — fires once when the screen is instantiated; bind UXML elements here- `OnScreenEnter(context, CancellationToken)` — async; screen is now active- `OnScreenPause(CancellationToken)` — async; another screen was pushed on top- `OnScreenResume(CancellationToken)` — async; returned from a pushed screen- `OnScreenExit(CancellationToken)` — async; about to leave the stack- `OnScreenDestroy()` — final cleanup- Configurable timeout (default 5s) protects against hung async hooks- `OnNavigatingAway()` virtual override returns `bool` to block forward navigation (dirty-form gate)- `OnBackPressed()` virtual override returns `bool` to consume the back action- `OnBeforeNavigate` event for global navigation hooks- `GetNavigationData()` / `TryGetNavigationData()` for typed data passingTransitions- Built-in: `Fade`, `Slide` (Left, Right, Up, Down with auto-reverse on pop), `Scale`, `Crossfade`, `None`- `TransitionConfig` — per-screen duration, easing, direction; serialized in the `ScreenRegistry`- `IScreenTransition` interface — implement for custom transitions- `ScreenTransitionBase` — USS-driven base class for class-toggle-based custom transitions- `IConfigurableTransition` — optional interface; custom transitions receive Inspector-configured duration / easing- `[CustomTransitionType]` attribute — registers a custom transition in the Inspector dropdown- `TransitionProvider` static factory — sibling assets register at runtime to override built-in transitions- Two-frame USS timing model with `duration + 200ms` safety timeoutBack button + input- Hooked into UI Toolkit's `NavigationCancelEvent` (Escape, Android hardware back, gamepad B / Circle)- `EnableBackButton` flag on `ScreenManager` to opt out- `OnBackAtRoot` event fires when back is pressed at the root screen- `InputBlocker` transparent overlay blocks pointer + navigation events during transitionsDeep linking- `NavigateToAsync(target, stackPath)` constructs intermediate screens silently- Back navigation walks the synthetic stack naturally- Carry typed data through `NavigationOptions.Data`Screen loading- `ScreenRegistry` ScriptableObject — central registration of every `ScreenDescriptor`- `ScreenLoadMode.Lazy` (default) / `Preload` (at startup, `OnScreenCreated` fires immediately for binding) / `OnDemand` (via `PreloadScreenAsync`)- `BackStackBehavior.Standard` / `SkipOnBack` / `NoHistory`- `DefaultScreenFactory` — reflection-based instantiation- `IScreenFactory` — replace with a Zenject / VContainer / pooled implementation; documentation includes worked examples for all threeExtensibility- `IScreenFactory` for custom instantiation (DI container, object pooling)- `IScreenHost` for custom container management in the visual tree- `IScreenTransition` for custom transitions- `ScreenEventBus` — static pub / sub; sibling assets subscribe without hard references- Stack queries: `IsInStack(screenId)`, `CanGoBack`, `GetStackSnapshot()`Cross-asset integrations- `Tools > KrookedLilly > Screen Manager Setup` is the one-stop panel for enabling integrations with every installed sibling that consumes from Screen Manager: Focus & Navigation, Modal & Notifications, Theme Switcher, Form Validation, Data Binding, ECS Bridge. One toggle per integration; integrations ship disabled by default.- The reverse-direction integration with Tween Engine is toggled from `Tools > KrookedLilly > Tween Engine Setup` and adds 4 `IScreenTransition` implementations (Fade, Slide, Scale, Crossfade). Screen Manager's panel surfaces it as a read-only "Consumes from" row with a one-click deep-link to Tween Engine's panel.Editor- `ScreenManagerInspector` — embeds the sibling `UIDocument` inspector inside a "UI Document" foldout (prevents Unity's built-in inspector from throwing `MissingReferenceException` on play mode exit); runtime debugging panel shows active screen, stack contents, transitioning status, and manual push / pop / replace controls- `ScreenRegistryInspector` — inline validation with a "Validate All" button; per-entry warnings for missing UXML, duplicate IDs, or unknown screen types- Auto-validation on Play via `[InitializeOnEnterPlayMode]`- Setup panel (`Tools > KrookedLilly > Screen Manager Setup`) — enable / disable Screen Manager integrations with any installed sibling assetIncluded demos- `GameDemo` — five-screen game flow (Main Menu, Settings, Gameplay HUD with coin-catching mini-game, Pause Menu, Game Over) covering push / pop / replace, deep linking, lifecycle hooks, typed data, `BackStackBehavior` variants, and `ScreenLoadMode.Preload`- `MacroTrackerDemo` — nutrition-tracker flow with realistic data-driven screen navigation and typed data passingCompatibility- Unity 6+ (6000.0 and newer)- UI Toolkit (com.unity.modules.uielements)- Mono + IL2CPP (Standalone verified; iOS / Android / WebGL / consoles supported via standard AOT path)- URP, HDRP, Built-in render pipelines- Full C# source, no DLLs- XML documentation on all public APIs- Zero external dependenciesAI (Claude Code) was used as a development assistant throughout the package creation process. This includes code generation, architecture design, writing unit tests, documentation authoring, and debugging. All AI-generated code was reviewed, tested, and validated by the developer. The final package is 100% human-supervised C# source code with no AI runtime components.



