Start with the UI Toolkit root you already own.
Create a GameObject, add UIDocument, and assign Panel Settings as you would for any UI Toolkit screen. LumaFlow does not replace this integration point; it mounts below the document’s root element.
Your MonoBehaviour owns the UIDocument and the returned MountHandle. The framework owns only its child host and the tree under that host.
Mount once when the host becomes active.
Create a component on the same GameObject. The first version can render a static screen; the lifecycle is already the production lifecycle.
using LumaFlow;
using UnityEngine;
using UnityEngine.UIElements;
using Framework = LumaFlow.LumaFlow;
[RequireComponent(typeof(UIDocument))]
public sealed class ProjectCounterScreen : MonoBehaviour {
private MountHandle? _mount;
private void OnEnable() {
var root = GetComponent<UIDocument>().rootVisualElement;
_mount = Framework.Mount(BuildScreen(), root);
}
private static Widget BuildScreen() =>
new Text("Projects");
}Make the changing value explicit.
A widget is an immutable description, so the counter lives outside the description. ReactiveBuilder<T> is the branch that reads the value and therefore the branch that updates.
private readonly State<int> _count = new(0);
private Widget BuildScreen() => new Column(
gap: 12f,
children: new Widget[] {
new Text("Project overview"),
new ReactiveBuilder<int>(
_count, value => new Text($"{value} active projects")),
new Button("Add project", () => _count.Value++)
});Do not instantiate long-lived controllers or state inside a builder. Builders can run again; the component is the owner that survives those updates.
Dispose when the document stops being your active host.
Disposal removes LumaFlow’s host and releases subscriptions. It does not clear native siblings that your application added to the document root.
private void OnDisable() {
_mount?.Dispose();
_mount = null;
}Take the same model into a real application.
Responsive composition
Use LayoutBuilder to switch between compact and wide layouts from real constraints.
Application flow
Introduce a retained Navigator when the screen becomes a route.