Skip to content

kids.kapish.flexui

unity

Flex-based UI layout and rendering framework for Unity. Replaces Unity's built-in UI system with CSS flex-inspired layout, pluggable render pipeline integration, and a structured lifecycle.

Installation

Add to your Unity project's package manifest:

json
{
  "kids.kapish.flexui": "file:../../src/unity/kids.kapish.flexui"
}

Plus one render pipeline package (see below). Requires Unity 6000.0+.

Architecture

Hierarchy

FlexUI is built on Unity's GameObject hierarchy. A FlexCanvas is the root - it owns the layout context and spatial configuration (camera binding, coordinate system). Under it, FlexTransform nodes form the layout tree. Each node can have sibling FlexBehaviour components (visuals, groups, signals, text).

Layout Model

Layout uses a frame-based box model similar to CSS:

┌─ Margin ──────────────────────┐
│ ┌─ Content ────────────────┐  │
│ │ ┌─ Padding ───────────┐  │  │
│ │ │                      │  │  │
│ │ └──────────────────────┘  │  │
│ └───────────────────────────┘  │
└────────────────────────────────┘

Each axis (horizontal/vertical) is configured independently with mode (Fixed, Fill, Wrap), size, anchor, and spacing. The FlexTransformFrame resolves these into concrete rects during layout.

Lifecycle

The lifecycle is a structured pipeline that broadcasts to every node in the hierarchy:

  1. Awaken - forward pass: nodes initialise. Reverse pass: confirm ready.
  2. FindRelationships - forward: discover siblings. Build FlexBehaviourCollection. Reverse: relationships confirmed.
  3. Layout - forward: measure and position. Reverse: finalise rects.
  4. Render - forward: prepare visuals. Execute render callback. Reverse: cleanup.

Forward broadcasts walk root→leaves. Reverse broadcasts walk leaves→root. This ensures parents know their children are ready before finalising.

Rendering

The renderer is pluggable via FlexRenderer.Register(pipeline, renderer). Each render pipeline package registers its IFlexRenderer implementation at editor startup via [InitializeOnLoad].

The URP package is the most complete - it provides a ScriptableRendererFeature that hooks into the URP render graph, plus a scene preview system that runs layout and renders visuals directly in the Scene view.

Signals

Two distinct concepts share this name inside FlexUI:

  1. FlexUI pointer signals (the FlexSignal* types) propagate pointer/mouse input through the flex hierarchy. FlexSignalSenderMouse generates signals from Unity's mouse input, which propagate down through FlexSignalReceiver components. FlexSignalBlocker stops propagation. This replaces Unity's EventSystem for FlexUI hierarchies.
  2. Runtime API signals (Signal<T> from kids.kapish.signals) are the typed pub/sub mechanism FlexUI uses for a handful of external-facing notifications: FlexSpatial.ScreenResolutionChanged (Signal<Vector2>) and IFlexTransform.FlexLayoutCompleted (parameterless). Subscribe with .Add(handler) and call the returned Action to unsubscribe, or use .Remove(handler).

Note: editor-only events that wrap Unity editor hooks (e.g. Flex.DuringSceneGUI, FlexEditor.BeforeSceneGUI) are intentionally kept as plain event Action and were not migrated to Signal<T> — they mirror the underlying Unity editor event shape.

Visuals

Visual components (FlexVisualImage, FlexVisualPanel, FlexVisualMaterial) generate meshes and materials for rendering. They implement IFlexRenderable - providing mesh, material, and a rect. The visual state system (FlexVisualState) drives property transitions (colour, opacity, scale) in response to signals.

Text

SDF text rendering with multi-layer font assets. FlexTextFontAsset holds glyph sets with per-layer rendering (fill, outline, shadow). The font baker editor window generates these assets from source fonts.

File Structure

Runtime/
├── Core/            # FlexBehaviour, IFlexNode, IFlexRenderable, units
├── Transforms/      # FlexCanvas, FlexTransform, relationships
│   └── Frame/       # Box model: axis config, spacing, frame resolution
├── Layout/          # Layout algorithms, aspect fitting
├── Groups/          # Vertical/horizontal group layouts
├── Lifecycle/       # Lifecycle runner, stages, progress
├── Rendering/       # IFlexRenderer, FlexRenderer registry
├── Visuals/         # Image, Panel, Material visuals
│   └── State/       # Visual state machine
├── Signals/         # Input signal propagation
│   ├── Send/        # Signal senders (mouse)
│   └── Receive/     # Receivers, blockers
├── Spatial/         # Coordinate conversion, canvas modes
├── Text/            # SDF text, font assets, glyphs
└── Actions/         # Action base

Editor/
├── Inspectors/      # Custom editors for FlexUI components
├── Styling/         # FlexEditorRow styled inspector helpers
├── Icons/           # Editor icons
├── Windows/         # Font baker window
└── Extensions/      # GUI extensions

Dependencies

DependencyKind
kids.kapishruntime (Carrot core Unity package)
kids.kapish.signalsruntime (typed Signal<T> used for FlexSpatial.ScreenResolutionChanged, IFlexTransform.FlexLayoutCompleted)

Build

Import via Unity Package Manager. Requires Unity 6000.0+.


Using kids.kapish.flexui

Flex-based UI layout and rendering for Unity - CSS-like flex semantics with pluggable render pipeline support.

Setup

  1. Add kids.kapish.flexui and a render pipeline package (e.g. kids.kapish.flexui.urp) to your Unity project.
  2. For URP: run Tools → FlexUI → Install URP Renderer Feature to add the render feature to your URP pipeline.

Common Patterns

1. Create a FlexUI hierarchy

Canvas (FlexCanvas)
├── Header (FlexTransform + FlexVisualPanel)
│   └── Title (FlexTransform + FlexText)
├── Content (FlexTransform + FlexGroupVertical)
│   ├── Item 1 (FlexTransform + FlexVisualImage)
│   └── Item 2 (FlexTransform + FlexVisualImage)
└── Footer (FlexTransform + FlexVisualPanel)

Add FlexCanvas to a root GameObject. Add FlexTransform to each child. Add visuals, groups, and text as sibling components.

2. Configure axis layout

Each FlexTransform has horizontal and vertical axis settings:

  • Mode: Fixed (explicit size), Fill (expand to parent), Wrap (shrink to content)
  • Size: in flex units (px-like)
  • Anchor: where the element sits within its available space
  • Spacing: margin and padding per axis

3. Group layouts

Add FlexGroupVertical to a FlexTransform to stack children vertically with configurable alignment and spacing:

  • Alignment: start, center, end, stretch
  • Spacing: fixed gap, space-between, space-around

4. Visuals

  • FlexVisualPanel - solid colour / material panel
  • FlexVisualImage - sprite/texture image
  • FlexVisualMaterial - custom material rendering

All visuals generate meshes sized to the transform's content rect.

5. Visual states

Attach a FlexVisualStateAsset to drive property transitions:

  • Define states (default, hover, pressed, disabled)
  • Each state sets colour, opacity, scale, or custom material properties
  • States transition automatically in response to signals

6. Signals (input)

Add FlexSignalSenderMouse to the canvas to generate pointer signals. Add FlexSignalReceiver to elements that should respond to input. Use FlexSignalBlocker to stop signal propagation.

7. Text

Add FlexText to a transform alongside a FlexTextFontAsset reference. The SDF renderer supports multi-layer fonts (fill + outline + shadow).

Use the Font Baker window (Editor → FlexUI → Font Baker) to generate font assets from source fonts.

8. Scene preview (URP)

The URP package provides real-time scene preview:

  • Show Layout - draws margin/content/padding rects as wireframes
  • Show Visuals - renders visual components directly in the Scene view
  • Play Always - continuous refresh (useful for animations)

Toggle via the Flex UI overlay in the Scene view toolbar.

Tips

  • Layout runs every frame - it's designed to be cheap. Don't cache layout results manually.
  • Lifecycle order matters - Awaken → FindRelationships → Layout → Render. Don't access relationships during Awaken.
  • One render pipeline package - install only the one matching your project's pipeline.

Package Contents

kids.kapish.flexui.urp

Namespace: FlexUI.Rendering.URP

Runtime

FlexRendererURP - IFlexRenderer implementation; discovers the FlexRendererURPFeature from the URP pipeline asset

FlexRendererURPFeature - ScriptableRendererFeature; creates and enqueues the render pass. Exposes PreviewSettings (show layout, show visuals, play always)

FlexRendererURPRenderPass - ScriptableRenderPass; uses RenderGraph API, attaches to camera colour buffer

Editor

FlexRendererURPStartup - auto-registers the URP renderer via [InitializeOnLoad]

FlexRendererURPSetup - menu item: Tools → FlexUI → Install URP Renderer Feature

FlexRendererURPScenePreview - renders layout wireframes and visuals in Scene view using Handles and CommandBuffer

FlexRendererURPSceneToolbar - Scene view overlay with toggles for preview settings

FlexRendererURPSceneHeartbeat - editor update loop for continuous scene repaint when Play Always is enabled


kids.kapish.flexui.hdrp

Namespace: FlexUI.Rendering.HDRP

Runtime

FlexRendererHDRP - IFlexRenderer stub for HDRP

Editor

FlexRendererHDRPStartup - auto-registers via [InitializeOnLoad] when HDRP is the active pipeline


kids.kapish.flexui.birp

Namespace: FlexUI.Rendering.BiRP

Runtime

FlexRendererBiRP - IFlexRenderer stub for Built-in Render Pipeline

Editor

FlexRendererBiRPStartup - auto-registers via [InitializeOnLoad] when BiRP is the active pipeline

Carrot