Migrate from uGUI to Luna

This page is for projects whose UI lives in uGUI: Canvases, RectTransforms, TextMeshPro. If your project already uses UI Toolkit, skip straight to Adopt Luna in an Existing UITK Project.

Moving from uGUI to Luna is two migrations, and it pays to keep them separate in your head: first uGUI to UI Toolkit (a different UI system, not a different version of the same one), then plain UITK to Luna (a design system + workflow on top of UITK). The second half is the staged path on the UITK adoption page; this page gets you through the first half and tells you what not to port.

Both UI systems run side by side in one project without conflict, so you migrate screen by screen while the game stays shippable.

The conceptual jump

Do UI Toolkit Basics first; it is short. Then use this table as your translation dictionary while porting:

uGUI habitUITK / Luna replacement
Canvas + CanvasScalerPanel Settings asset referenced by a PanelRenderer. Luna ships a configured one (LunaPanelSettings); scaling strategy lives there, not per screen
One GameObject per element, RectTransform anchorsA UXML document; elements are lightweight VisualElements laid out by flexbox, not GameObjects
Nested prefabs for reusable widgetsUXML templates + USS classes; Luna's components replace the widget prefabs you built yourself
Image components + sprite slicing for panels, borders, glowUSS backgrounds and Luna's UI Effects (glow, outline, shadow, gradient, pattern) with no textures at all
TextMeshProUITK's built-in SDF text. Luna's theme wires the font fallback chain; Text Effects covers the animated-text ground TMP plugins used to
Button.onClick wired in the InspectorQuery the element once, subscribe in code; under Luna views this lives in OnUILoaded (First View)
Animator / tweening plugins on RectTransformsUSS transitions plus Luna's Transition Animation presets and Interaction Juice
CanvasGroup alpha + SetActive for show/hideLuna view lifecycle: stack push/pop with automatic fades and occlusion (Navigation Graph)
World-space CanvasWorld-space UITK via LunaPanelSettingsWorldSpace (Theme Stack)
Particles / 3D models over UI via camera stacking or pluginsUI Render: camera to render texture to UI element, managed for you

Port structure, not pixels

The single biggest time sink in uGUI migrations is rebuilding each screen 1:1, anchor by anchor. Do not. Rebuild each screen's structure in UXML (what it contains, how it groups), then let Luna's theme and components supply the visual layer you used to hand-place:

  1. List the screen's content, not its GameObjects: "header, resource bar, scrollable item grid, two action buttons".
  2. Author that structure in UXML using standard controls plus Luna components (GridView for the item grid, class="btn" buttons, a ProgressBar for the resource bar).
  3. Style with USS classes, leaning on the theme tokens and utility classes. Resist recreating exact uGUI pixel positions; flexbox spacing is the point.
  4. Port the controller logic: your uGUI controller's serialized references become element queries, and its public API can stay identical, which keeps the rest of the game code untouched.

Screens that are mostly decoration (sliced sprites, baked glows, drop shadows) usually come out smaller in UITK because UI Effects generates that look from the shader.

Then follow the staged path

From here your migrated screens are ordinary UITK, and the rest is exactly the UITK adoption path:

  • Stage 0 + 1 (install, theme): do these before porting your first screen, so every screen you port lands themed from day one.
  • Stage 2 (components + features): this is step 2 of the porting recipe above; you are already doing it.
  • Stage 3 (views + navigation): port each screen directly into a view prefab rather than a bare PanelRenderer. Since you are rebuilding the screen anyway, going straight to the end state costs nothing extra, unlike the UITK-native case where screens already work.

The same ordering advice applies: next new screen first, then modals (Confirmation and Input popups ship ready), then leaf screens, shell last. And check Views before porting each screen; Settings, Save & Load, Main Menu, Pause, and Inventory already exist as extendable views.

Doing this with an AI agent

uGUI-to-UXML conversion is mechanical enough that AI agents handle it well when they can read the target patterns. This site publishes every docs page as raw markdown for exactly that; see AI Development for setup and migration prompts.

Settings

Theme

Light

Contrast

Material

Dark

Dim

Material Dark

System

Sidebar(Light & Contrast only)

Light
Dark

Font Family

DM Sans

Wix

Inclusive Sans

AR One Sans

Direction

LTR
RTL