UI Toolkit: ECS Bridge OFFICIAL SALE

Driving a UI from DOTS means writing the same sync loop over and over: query the entity, read the component, copy the value into a label — every frame, for every stat. Add a health bar, an ammo counter, and a score, and you are maintaining a hand-rolled HUD system that breaks every time the data model shifts. Unity's own runtime binding can't help here: it reads managed objects, and your gameplay state lives in unmanaged ECS chunks it cannot see.


ECS Bridge is the binding layer DOTS never had. Mark a component, bind a VisualElement to a field, and it stays in sync — change-detected so unchanged values cost nothing, source-generated so the hot path stays Burst-friendly with zero reflection. The registry installs itself the first time you bind, ticks once per frame, and auto-disposes when an element leaves the panel.


One line per binding.

healthLabel.BindComponent<PlayerHealth>(entity, h => h.Current, BindTarget.Text, "HP: {0}");
healthBar.BindComponent<PlayerHealth>(entity, h => (float)h.Current / h.Max, BindTarget.StyleWidthPercent);
hudPanel.BindComponentToClass<PlayerHealth>(entity, h => h.Current * 5 < h.Max, "low-health");

Read any field through a strongly-typed lambda and write it to label text, a style value, a USS class, or visibility. Rename the field and the binding follows — no string paths, no runtime "field not found" surprises.


Singletons and global state.

Bind a label straight to an ECS singleton with BindSingleton<T> — ideal for score, wave number, or any game-state component, with no entity reference needed. For state that doesn't live on an entity at all — locale, settings, debug flags — ReactiveState<T> gives you an observable value with BindReactive and BindReactiveToClass, updated event-driven with zero per-frame cost while nothing changes.


Queries and aggregations.

Drive a label from a whole EntityQuery, not just one entity. BindCount, BindAny, and BindAggregate (Sum, Average, Min, Max) recompute as entities spawn and despawn. Bind a query straight to a ListView, ScrollView, or MultiColumnListView and the collection follows the world.


Events, thresholds, and async.

React to change instead of polling: OnComponentChanged, OnComponentThresholdCrossed, OnComponentIncreased / OnComponentDecreased, plus entity-lifecycle hooks OnEntityCreated and OnEntityDestroyed. Prefer to await? WhenComponentChangedAsync, WhenComponentThresholdCrossedAsync, and WhenEntityCreatedAsync return tasks with full cancellation support.


Two-way and commands.

UI can write back to ECS. BindTwoWayViaECB routes edits through an EntityCommandBuffer so writes coexist safely with running systems, and Button.BindCommand / BindCommandSingleton wire a button straight to a gameplay action.


Author HUDs in UXML.

Skip the per-label C# entirely — put the binding in the markup:

<engine:Label text="@ecs:PlayerHealth.Current,Max of #player as 'HP: {0} / {1}'" />

Then activate the whole document with a single root.BindEcsDocument(world, ("player", entity)) call. Malformed or unresolved markers warn once and skip — they never throw.


Change-detected, zero-allocation hot path.

Every binding supports three update strategies — Polling, Change Detection (the default), and Manual — switchable live with SetStrategy. Change detection suppresses writes for values that didn't move, so a thousand idle bindings cost almost nothing. Built-in Unity.Profiling markers and per-frame diagnostics (TicksThisFrame, WritesThisFrame, SkippedThisFrame) show exactly what the registry is doing.


See every binding live.

Window > KrookedLilly > ECS Bridge Inspector lists every active binding with its target, strategy, and entity, plus running tick and write counters and name/strategy filters — for leak hunting and for confirming a binding is actually firing.


Nine demo scenes included.

HealthBar — three bindings on one entity (label, bar fill, low-health USS class). 


ScoreCounter — a singleton-driven score. 


PlayerHUD — five concurrent bindings across an entity, a singleton, and a USS class. 


AggregationShowcase — Count / Sum / Average / Min / Max / Any from one query. 


ReactiveState — non-ECS locale and debug-level globals. 


ComputedField — [BindableComputed] properties as binding sources. 


StressTest — 1000+ entities, aggregations staying reactive while change detection saves cost on idle frames. 


UpdateStrategyComparison — Polling vs Change Detection vs Manual side by side. 


UxmlBinding — a HUD authored entirely in UXML @ecs: markers. Every scene ships with controller scripts, UXML, USS, and panel settings.


Part of the UI Toolkit Components suite.

ECS Bridge is one of the KrookedLilly UI Toolkit Components. If you own sibling assets from the suite, cross-asset integration setup lives in one place — the unified Tools > KrookedLilly > Setup window


Builds for every platform.

Builds clean under IL2CPP and uses the standard Unity AOT path that runs on desktop, iOS, Android, WebGL, and consoles. A bundled link.xml protects the runtime assembly and the source-generated accessors from managed-code stripping; the troubleshooting guide covers the rare project that needs more.


Full C# source.

Complete C# source with XML documentation on every public API. The only binary is the Roslyn source generator that turns [BindableComponent] into Burst-friendly accessors — Unity requires source generators to ship as precompiled analyzers, so it travels as a labelled DLL inside the package.