UI Toolkit: Motion Importer
Lottie and sprite-sheet players for Unity 6 UI Toolkit. LottieImage and SpriteAnimation custom VisualElements; pure-C# Lottie renderer; reads Sprite Editor slices; Theme Switcher tinting.
by KrookedLilly
Price History +
Animation content authored outside Unity — Lottie JSON from After Effects, sprite sheets from frame-by-frame tools, branded logo animations from your designer — has no native home in UI Toolkit. You drop in a UIDocument and find no way to drag a Lottie file onto a panel. Sprite sheets need a UV-rect helper you write from scratch. Frame-by-frame icon animations live on Animator components that UI Toolkit can't bind to.
This asset is the missing import layer. Two custom VisualElements drop straight into UXML: <LottieImage> plays Lottie JSON via a pure-C# managed renderer, and <SpriteAnimation> plays sprite sheets via the standard Unity Sprite Editor workflow with no manual Columns/Rows entry. Zero allocations during steady-state playback. No native plugins required.
Lottie playback in three lines.
var lottie = new LottieImage { Asset = myLottieAsset, AutoPlay = true, Loop = true };
lottie.OnComplete += () => Debug.Log("loop finished");
parent.Add(lottie);
Drag a .lottie.json file into your project and Unity's custom importer turns it into a LottieAnimationAsset with parsed metadata (frame rate, frame count, dimensions, markers). Drop the asset onto a <LottieImage> element and it plays. Full control surface: Play, Pause, Stop, GoToFrame, GoToProgress, Speed, plus events for OnPlay, OnPause, OnStop, OnComplete, OnFrame, and OnMarker.
Pure C# renderer — no native plugins.
The managed Lottie renderer paints image layers and shape layers (ellipse, fill) with animated transforms (position, anchor, scale, rotation, opacity) directly through UI Toolkit's Painter2D and child VisualElements. Parent-chain transforms cascade correctly so nested layers inherit their parent's scale and rotation. Designed for branded logo animations, icon flourishes, and UI accents — the kind of content most mobile and desktop apps actually use.
Sprite sheets the way Unity already works.
<motion:SpriteAnimation sheet="Hero" frames-per-second="12" auto-play="true" loop="Loop" />
Slice your sheet in Unity's Sprite Editor (Grid By Cell Count) and drop the resulting Texture2D onto a <SpriteAnimation> element. The asset auto-detects the slice sub-assets via AssetDatabase and plays each Sprite's own rect — no Columns/Rows entry, no double-bookkeeping with what you already told Unity. For un-sliced PNGs, the grid-mode fallback uses Columns/Rows attributes from UXML or inspector overrides.
Three loop modes plus sub-range playback.
sprite.Loop = LoopMode.PingPong;
sprite.PlayRange(8, 15); // play frames 8–15 of a multi-pose sheet
sprite.SetFrames(spriteList); // or supply a hand-curated frame list
Once / Loop / PingPong for the playback pattern. PlayRange(start, end) for sheets that pack multiple animations on one texture (walk left, walk right, idle, attack — pick any range). Sprite-list mode (SetFrames) when you have pre-curated sprites that aren't in a grid. Frame tags via SetFrameTag fire callbacks at specific frames for game logic.
Zero allocations during steady-state playback.
SpriteAnimation adjusts UV rect via background-position and background-size — single texture, no per-frame allocation, batch-friendly. A single PlayerLoop hook ticks all live elements; no MonoBehaviour per animation. Stop a panel, swap UIDocuments, destroy a scene — the runtime cleans up automatically.
Theme-aware logos via the optional Theme Switcher integration.
If you also own UI Toolkit: Theme Switcher, one extension method recolors a Lottie logo to match the active theme:
themeManager.BindLottieTint(logo, "--color-brand-primary");
The tint applies to both raster image layers and vector shape fills, and follows live theme switches automatically. The binding cleans itself up when the element leaves its panel. The integration ships disabled by default — open Tools > KrookedLilly > Setup and enable the Theme Switcher → Motion Importer integration.
Four demo scenes included.
SpriteBasicDemo — drop any sliced sheet onto the controller; the demo plays it with Play / Pause / Stop / Prev Frame / Next Frame controls and a live frame readout.
SpriteLoopModesDemo — same sheet rendered three times side-by-side in Once, Loop, and PingPong modes.
SpritePlayRangeDemo — four-direction walk cycle on a single sheet (Left / Right / Forward / Backward); each button calls PlayRange to switch the active row without reloading the texture. Frame ranges are Inspector-configurable to fit any sheet's row layout.
LottieLogoDemo — .lottie.json playback with Play / Pause / Stop / 0.5× / 1× / 2× speed controls plus a tint row (Red / Cyan / Amber) demonstrating the TintColor property. All four scenes ship with controller scripts, UXML, USS, and configured panel settings.
Plays well with the rest of the UI Toolkit Components suite.
<LottieImage> and <SpriteAnimation> are ordinary VisualElements, so they compose with the rest of the suite naturally. Drop a Lottie inside a UI Toolkit: Screen Manager screen — it auto-pauses when the screen detaches. Inside a UI Toolkit: Modal & Notifications overlay — it works without special handling. Bind its properties (Asset, IsPlaying, Speed, CurrentFrame, TintColor) via UI Toolkit: Data Binding — standard UITK bindings work out of the box. UI Toolkit: Focus & Navigation receives focus events on either element when focusable="true".
Cross-asset integrations ship disabled by default and are enabled from a single unified window — open Tools > KrookedLilly > Setup to toggle the integrations that consume from Motion Importer and review the providers it consumes from.
Works on every platform.
Verified on Mac Standalone IL2CPP. Uses standard Unity AOT and UnityEngine.UIElements — supported on iOS, Android, WebGL, and consoles via the standard AOT path.
Full C# source, no DLLs.
XML documentation on every public API. Zero external dependencies.