| Version | Date | Summary | Breaking |
|---|---|---|---|
| 2.1.3 | 2026-08-17 | Kinetic scroll family (Carousel, LunaScroller, LunaListView); Carousel shelf mode + arrows; UI Render Snapshot mode with caching; statics cleared per play session; GridViewList on the Luna list stack; live-reload stability (incl. backdrop fix); TabView legacy-markup loud guard; partial safe-area insets; punch presets + asset node; localized-text casing; boot theme guard; .btn split into feel + .btn-solid look; nav Hidden While Open + loud external-close; per-open view lifecycle; dialogue views configurable before load; press-to-continue transitions in the runtime; DeferOneTick for panels spawned from load hooks; GameFull Settings unsaved-changes confirm; Showcase badge + leaderboard layout fixes | ⚠️ .btn skin opt-in; GridViewList list internals; pagination auto-hides single page; ListViewWrapper removed; UI Render scene color now opt-in |
| 2.1.2 | 2026-08-05 | One localized-text runtime API: BindLocalizedText extensions + LunaLocalization; notification localization glue consolidated | ⚠️ NotificationLocalization, LocalizedVisualElement removed |
| 2.1.1 | 2026-08-03 | Responsive hardening: phone-shaped editor views scale like phones, density sanity against wrong dpi, Enter-Play-Mode-Options fixes, plus a responsive tooling suite | — |
| 2.1.0 | — | View fades now truly animate; automatic z-order for nav views; snappier 0.2s default fade | — |
| 2.0.2 | — | Navigation scopes demo in Showcase Components; GameFull main-menu graph containment fix | — |
| 2.0.1 | 2026-07-30 | Playtest hardening: view-load reliability, nav diagnostics redesign, EsportLobby sample, CellBar and OrbitView, per-push notification args | ⚠️ NavDestinationResolver removed |
| 2.0.0 | 2026-07-11 | The UI-focused Luna — shader UI Effects, node-graph navigation, PanelRenderer view layer, UI Attractor, responsive theming, one bundled Asset Store package | ⚠️ from 1.x |
| 1.4.0 | — | UI Render system, Transition Animation system, ProgressBar events | — |
| 1.3.7 | — | Gap line overlays, tooltip disabled state; CelledProgressBar removed | ⚠️ Yes |
| 1.3.6 | — | Radial progress bar arc configuration (sweep / start angle) | — |
| 1.3.5 | — | Celled progress bar, radial multi-segment; UpdateProgressSegments() removed | ⚠️ Yes |
| 1.3.4 | — | Global UIView registry, LocalizationViewStyleSwitcher | — |
| 1.3.3 | — | Text Effects (12 rich-text effects), VertexReveal | — |
| 1.3.2 | — | Button shade/outline styles, ListViewWrapper | — |
| 1.3.1 | — | PaginationController + KeyValueDatabase editor improvements | — |
| 1.3.0 | — | World-space support (Unity 6.2), shader demos (Unity 6.3), RPGDemo | — |
| 1.2.3 | — | GameFull sample, SpeechBubble tails | — |
| 1.2.2 | — | InputPrompt local multiplayer | — |
| 1.2.1 | — | ProgressBar IndicatorAutoColor; fixes | — |
| 1.2.0 | — | Mobile sample, GridView/Inventory list variants, AspectRatio element | ⚠️ Yes |
| 1.1.1 | — | ProgressBar USS variables; Save/Load UI redesign | — |
| 1.1.0 | — | Tooltip system rework, functional save system | ⚠️ Yes |
| 1.0.8 | — | Notification sfx options; fixes | — |
| 1.0.7 | — | CooldownWipe element | — |
| 1.0.6 | — | Custom Tab component | — |
| 1.0.5 | — | PauseMenuEscapeAction plain class, split fade durations | — |
| 1.0.4 | — | CircleHoleElement, Ink sample | — |
| 1.0.3 | — | ProgressBar overlay feature | — |
| 1.0.2 | — | Add Default Escape Action option | — |
| 1.0.1 | — | Disable Other Views On Fade-In option | — |
The playtest rollup. A new kinetic scroll family (Carousel, LunaScroller, LunaListView) built on one shared gesture core (family hub), live-reload stability, partial safe-area insets, punch presets, localized-text casing, a boot theme guard, and layered button classes:
btncarries the feel,btn-solidopts into the look. GridViewList now renders through the Luna list stack. TabView screams on legacy markup instead of silently stacking tab contents, and GameFull Settings gained an unsaved-changes confirm through the global confirm destination.
⚠️ Upgrade note: this release adds library sheets (
LibScroller.uss,LibCarousel.uss) to the main theme. If your project imports the theme — directly or through the Essentials sample copy — force-reimport your theme chain after updating. Unity does not rebuild derived ThemeStyleSheets on its own; without the new sheets,LunaScrollerandLunaListViewcontent shrinks to min-content and nothing scrolls, which reads exactly like a broken component.AssetDatabase.GetDependencieswill still list the sheet — the reliable probe is readingresolvedStyleon an element carrying the class.
GridView SetCollapseEmpty. Empty slots can now collapse (display: none) instead of only hiding, so a partially filled row centers as a cluster instead of pinning left behind invisible cells. SetHideEmpty is unchanged. See GridView.
LunaListView MaxVisibleRows (max-visible-rows in UXML). When set, the list sizes itself to that many rows (fewer when the source is shorter) and scrolls the rest, so a container can hug a short list instead of stretching it. See LunaListView.
GridView multi-select filter groups. SetFilterMultiSelect(group, true) turns a filter group into a set: a filter button click toggles its filter in or out (ToggleFilter), the grid shows the union of the active filters (the group's -1 pass orders the result, so sorting is kept), and with nothing active every button of the group carries the selected class ("all"). SetActiveFilters(group, filters) sets the whole set at once (a supplies view that starts on meals and potions), IsFilterActive / GetActiveFilters read it. SetFilterOptions(group, allowed) declares the group's universe for a screen: values outside it are ignored and their buttons hidden, and "nothing active" means the union of the allowed values instead of everything (a supplies view whose two chips can both be toggled off still shows only meals and potions). Single-select groups, SetFilter / ClearFilter and the tab prompts behave as before.
GridView filter buttons keep their own color. SetSelectedFilterColor(null) (or an empty string) makes the view toggle only the selected-state class on filter buttons instead of also stamping a palette word, so buttons that already carry their own color class stay that color when selected. The default "sky" behavior is unchanged. See GridView.
Carousel. Carousel + CarouselDots: a horizontally paged strip that snaps to the nearest page on release — drag/flick with velocity sampling, settle duration + easing, page-width-percent peek for IAP-style offer strips, SnapTo / CurrentIndex / IndexChanged, and an indicator-dots element. Deliberately built on a plain container with its own gesture, not ScrollView, so the elastic-offset clamp bug cannot reach it. Ships with CarouselShowcase.unity. See Carousel.
Game-grade scroll container. LunaScroller: drag past an 8px threshold, flick into a momentum glide with tunable friction, rubber-banded ends with spring-back, mouse wheel, a styled draggable scrollbar with track click-jump, and scroll-into-view on gamepad/keyboard focus change. ScrollTo(offset | element) takes explicit (duration, easing) overloads. A horizontal Carousel composes inside a vertical scroller through axis-lock arbitration — whichever axis dominates at the threshold owns the gesture. Gestures work on button-covered surfaces (a shop column): the core rides along on a child's pointer capture and steals it only at the drag threshold, so taps still click and drags still scroll — and scroll-into-view ignores pointer-originated focus, so tapping a partly-visible control never repositions the container. Ships with ScrollerShowcase.unity. See Scroller.
LunaListView. A fixed-height virtualized list on LunaScroller — MakeItem / BindItem / ItemsSource / Rebuild() / RefreshItems() (following a growing and shrinking source per the Unity ListView.RefreshItems contract), rows outside the viewport recycled through a pool — plus single selection with the Unity-compatible event signature (SelectionType / SelectedIndex / SelectionChanged, toggle-notify on same-row click) and ScrollToIndex with ScrollAlignment (Auto/Start/Center/End; long animated jumps teleport and ease only the tail so binds stay bounded). Owns the slice GridViewList consumed from Unity's ListView; drag-reorder arrives demand-driven. Gamepad/keyboard navigation is built in: the list itself is focusable (rows are pooled and never focusable), Up/Down moves the selection cursor with ScrollToIndex follow — or scrolls row-by-row on selection-less lists — and at the boundary default navigation exits to the adjacent focusable. An UnbindItem callback completes the bind trio. See LunaListView.
Point-origin resource flights. UIAttractor Burst(panel, panelPosition, target, burst) and Burst(panel, camera, worldPoint, target, burst) fly particles from a point with no source element — a claimed card, a board pickup, a 3D reward — mirroring the panel/camera sources Spotlight grew. See UI Attractor.
Partial safe-area insets. SafeAreaConfig gained per-edge Scale (multiplier on the device inset, applied before Offset) and Max Inset (cap; Min Inset wins). On top of the global config, a single screen can override per element through USS: --luna-safe-area-scale and --luna-safe-area-max on the tagged wrapper, composing with breakpoints, no C#. Existing assets keep identical insets. See Responsive.
Punch presets. PunchScale / PunchTranslate / PunchRotate on the TransitionSequence builder: a damped oscillation from amplitude, duration, vibrato (oscillation count) and elasticity, expanded into plain steps and atomic inside Together(...). TransitionSequenceAsset gained a matching Punch node type (color-coded in the drawer), so asset-driven view transitions no longer need hand-authored keyframe approximations. See Transition Animation.
Localized-text casing. BindLocalizedText(..., casing: LunaTextCasing.Upper) re-cases every resolved value with the active locale's culture (Turkish i safe), works on Button too, and keeps live locale switching. UITK has no text-transform; this is the hook. See Localization.
Responsive settings, explained in place. Tooltips on every Responsive Settings field, labeled DeviceClassMode options, and a settings reference on the docs site.
Read-only nav queries. IsInStack(id) and CurrentId on the navigation stack, and the whole read-only query surface (StackDepth, CurrentNode, CurrentArgs, ActiveChannelPath, CaptureSnapshot(), ...) is mirrored on the static LunaNavigation facade, alongside a parameterless Pop() that closes without a result — Pop<T>(value) is only for resolving PushAsync<T>, and Pop(true) written out of habit reads like a flag while quietly resolving (or mis-resolving) an awaiter. For per-origin view behavior, push args remain the recommended pattern; see the note on Navigation.
Screen-space coordinate helpers. UITKCoordinateUtility.WorldToPanel(panel, camera, worldPoint) and PanelToWorld(element, camera, distance) for screen-space panels — they handle the y-flip that RuntimePanelUtils.ScreenToPanel does not, against camera.pixelHeight rather than Screen.height.
Spotlight fallback is discoverable. The one-time warning now says exactly what degrades without a Spotlight Filter Settings asset (CornerRadius/Softness ignored, hard-edged holes), and the Spotlight page carries the matching troubleshooting note.
Spotlight over rects and world points. LunaSpotlight.Focus(panel, rect, options) cuts the hole over a fixed screen region, and Focus(panel, camera, worldPoint, size, options) anchors it to a camera-world position and keeps following it while the camera moves — for tutorial cut-outs over board objects with no UI element under them. MoveTo(rect) animates between anchors of any kind, and clicking inside the hole advances under ClickTarget. See Spotlight.
Spotlight content layer. Captions, arrows and hand pointers used to render below the dim (the overlay is the panel's topmost child) and came out at 14% brightness. SpotlightHandle.Content is a container above the dim: Ignore-picking with opt-in children, fades with the dim, cleared on dismiss, with HoleRect / OnHoleChanged for positioning against the hole. The hole cuts a dedicated dim layer with the content layer as a sibling above it, so chrome straddling the cut-out (a hand at the target's corner, a badge on the highlighted button) renders whole — and both layers clip their children, so oversized chrome can never skew the hole. Tours render step Title/Caption into it by default (Luna-styled, auto-positioned, RenderDefaultCaption(false) to opt out), and SpotlightTourPlayer exposes the same surface (Content / HoleRect / OnHoleChanged, a runtime RenderDefaultCaption toggle) for custom tour chrome — the bundled SpotlightTour demo is rebuilt on it. The old parent-to-visualTree + BringToFront workaround fought nav z-order and is now documented as superseded. See Captions and content.
Dim without a hole, with elevation. LunaSpotlight.Dim(panel, options) (Shape.None) renders a full dim, and handle.Elevate(element) lifts a live element above it — pinned in place, still interactive, restored to its original parent on dismiss. Elevation mirrors the element's real ancestor chain as neutralized wrappers carrying names, classes and the ancestors' style sheets, so ancestor-scoped USS and the view's own <Style src> rules keep applying while lifted. The pin follows the element's placeholder every frame — dismiss fade included — so a container that animates away carries the lifted element with it (at most one frame behind a transform-animated container; instrument-visible, not eye-visible). See Dim without a hole for the short residue list.
Rethemable tooltip default. Tooltips whose setup passes no colors used to get hardcoded scarlet-900 / coral-400 utility classes from C#; they now wear tooltip_bg_default / tooltip_border_default, resolved by the --luna-tooltip-bg / --luna-tooltip-border theme variables (Essentials defines them with the same shipped look; the runtime library carries a matching fallback). Override two variables in your theme to restyle every plain tooltip; per-setup colors still win. See Tooltip.
Hidden While Open. A NavNode lists node ids whose open frames hide (nav-owned, restored on close/teardown) while this destination is open — a full-screen modal clears its scene's HUD shell and side menu with zero controller code. Restores are ownership-counted: when two open frames hide the same target (a full-screen view pushed from another full-screen view, both hiding the shell), it comes back only when the last holder lets go. Born from a consumer session where hand-rolled HUD hiding fought the stack; this is now the sanctioned way, with a hides badge on the graph node. See Navigation.
Per-open view lifecycle. UIViewComponent.OnViewShown / OnViewHiding virtuals fire on every open/close cycle (fade-settle / fade-out-start) — Unity's OnEnable/OnDisable fire once per scene for host-preloaded views whose GameObject stays active across close/reopen. See UIViewComponent.
Carousel marks the centered page. luna-carousel__page--active is stamped on the settled page, so "center = selected" styling (dim siblings, gate per-page chrome) is pure USS. See Carousel.
GridView slot-creation signal. GridViewBase.OnSlotCreated fires per slot as the layout pass materializes it — external passes over ItemSlots right after CreateSlots() miss the initial fill, because GridViewList's lines are built lazily by the list view. See GridView.
Self-close for views. LunaNavigation.PopSelf(id) and the UIViewComponent.PopSelf() shorthand close this destination and no-op unless it is the current one. PopBackStack closes whatever is on top, which is not necessarily the caller — anything finishing on its own schedule (a timer, a scroll-to-end, an awaited result) should close through PopSelf so a view can never pop a stranger's frame. Returning false means "not mine to close", an ordinary state rather than an error.
TabView guards legacy markup. A TabView still carrying pre-2.0 <ui:Tab> children now logs a loud error naming the element. That shape used to render every tab's content stacked with no warning — the headless TabView treats children as bar items and never toggles Tab bodies, which reads exactly like a layout bug. Migration: children are tab-bar Buttons; each Tab's content moves to a sibling .tab-panel element named after its tab button. See TabView.
Carousel becomes a shelf too. align takes start / center / end or any number 0..1 — it generalizes the existing centering math, so center is literally the 0.5 bias and every existing carousel is untouched. align="start" with clamp-to-edges turns the peek pager into a shelf: flush left, stopping flush right, with none of the dead space a centered pager deliberately keeps. page-sizing="Content" leaves your authored page width alone and measures the pitch instead — necessary whenever card width is breakpoint-driven, because a UXML attribute cannot follow breakpoints and USS can; pages are watched in both sizing modes, so a resize re-measures the pitch and PageCount / PagesChanged stay honest for carousels built at runtime. ReachablePageCount reports the stops a clamped shelf can actually make (trailing pages share the final offset), and the dots bind to it. See Carousel.
Carousel arrows. show-arrows="true" builds prev/next buttons over the strip's edges that step one page and disable themselves at each end. Drawn in USS rather than shipped as art, so a from-scratch theme gets a working chevron, and rethemed through --luna-carousel-arrow-* (size, inset, background, colour, radius, chevron weight). A negative inset places them outside the strip — the root no longer clips, an inner viewport does. The Showcase shop's item shelves now use exactly this instead of hand-rolled buttons. See Carousel.
UI Render Snapshot mode. For grids of 3D content — a roster of modular characters, an inventory of weapon models — where a live camera and render texture per cell is the actual cost. Snapshot renders one settled frame, copies it into a plain Texture2D, and hands the slot straight back to the pool: no camera and no render texture stay alive. Not to be confused with Once, which stops the camera but keeps everything allocated. The copy runs through AsyncGPUReadback (with a synchronous fallback) because a blocking read stalls the render thread and a grid capturing a dozen cells at once turns that into the very hitch this mode removes — so it lands a few frames later through OnSnapshotReady / SnapshotTexture. settleFrames (default 2) exists because Animators start on their bind pose and autoFrame measures the imported T-pose; handle.Snapshot() captures on demand when you know the model is posed. See Snapshot mode.
Snapshot caching. A cacheKey shares one capture between every cell showing the same thing, and a cache hit takes no slot at all — no camera, no render, no readback. This is what makes a virtualized grid affordable rather than merely differently expensive: without it, every cell recycled back into view re-renders its character. Least-recently-used with a capacity on the manager (default 64), plus ClearSnapshotCache() and InvalidateSnapshot(key). Keys are yours to compose because only you know what changes the image — an id alone is wrong the moment equipment or a skin changes the silhouette. ActiveRenderCount, PendingSnapshotCount and SnapshotCacheCount are exposed for perf HUDs. See Caching.
Shine is now a duty-cycled flourish (breaking look change). The shine effect used to be a thin band crawling continuously (one pass per cycle-time, always moving). Every shine cycle now runs a fast sweep (--luna-fx-shine-sweep-time, default 0.45 s), an optional full-surface glint as it finishes (--luna-fx-shine-glint-opacity / -glint-time), then rest — cycle-time becomes the seconds between shines. The luna-fx-shine preset ships the gold-CTA feel (wide soft band, one flourish every 4 s, brief glint). Every existing shine changes look; for a continuous crawl, set sweep-time equal to the cycle time with glint-opacity: 0. See UI Effects — Shine.
Press-to-continue transitions ship in the runtime. SceneLoadTransitionFadeWithInput / SceneLoadTransitionCircleWithInput moved from the GameFull sample into CupkekGames.Luna (same asset GUIDs, so the sample's dependencies prefab keeps resolving). A project that wants the "press any key" reveal no longer copies sample scripts. See Loading Screen.
DeferOneTick, and the load-hook contract written down. OnUILoaded (and OnViewRootChanged, UILoaded, WhenUILoaded, PanelRendererBinder.OnPanelReady) runs inside Unity's runtime panel update. Instantiating, destroying, or toggling a PanelRenderer-bearing GameObject there corrupts the panel iteration and throws Collection was modified one frame later from Unity's loop, with your code absent from the stack; every consumer that nests a panel (world-space speech bubbles, a dialogue prefab under a screen) used to hand-roll a one-frame delay. UIViewComponent.DeferOneTick(action) and LunaUIManager.DeferOneTick(action) are now the package-owned way to run the spawn on the next frame, and the hooks' XML docs and the site carry the rule. See Spawning other panels from a load hook and the troubleshooting entry.
GridViewList renders through LunaListView. Your UXML keeps declaring <ui:ListView> — construction replaces it in-place, carrying over the name, classes, inline sizing, fixed-item-height and scrollbar visibility — and gestures, momentum and the scrollbar are now Luna-owned, so the ScrollView elastic-clamp tail-jump on long touch lists is structurally gone. Breaking edges: the ListView property is now a compile error (use List), USS targeting the ListView type selector or unity-list-view class names must move to element classes, and the ScrollView-only responsive knobs (scroll mode, horizontal scroller, touch behavior, deceleration, elasticity) are ignored with a debug note. New UXML may also declare <luna:LunaListView> directly and have it used as-is — a matching constructor overload accepts one. Virtualized rows strip the w-full utility class (flow-mode grids keep it), so row geometry is fully USS-controlled via left/right/width on .luna-listview__row. See GridView.max(min-item-width, measured) — items now move down a line when they would not fit, where the old math bled the last cells off-screen on phones. min-item-width keeps its meaning as a floor; fixed SetFixedItemPerLine mode ignores measurement. See GridView..btn split into feel + look. btn alone now carries only the interaction feel (press/hover scale, transition, cursor), so sprite-skinned buttons stop being mangled by the default skin's slices and size clamp. The new btn-solid carries the previous look; class="btn btn-solid" renders identically to the old class="btn", and variants (ghost, outline, colors) compose on top unchanged. Bare btn neutralizes Unity's .unity-button default chrome in every state — including the hover/focus/active/disabled styling that out-ranks base rules through pseudo-class specificity — and solid buttons carry an explicit pressed background, so touch presses never fall through to foreign :active styling. Migration is a mechanical class edit; bundled components and samples are already migrated. See Button.TotalPages <= 1 — a pager showing "1" is almost never wanted. Default ON for every PaginationController consumer (GridViewPagination included); SetAutoHideSinglePage(false) restores the fixed footprint for screens that relied on it. See Pagination.ListViewWrapper and ListViewController removed. ListViewWrapper has had zero consumers since the save/load list moved to LunaListView, whose built-in focus navigation is the replacement; ListViewController was a legacy 1.x base with no consumers.NotificationHistoryView and the bundled NotificationModal render through LunaListView (their wrapper dropped), and CreditsView scrolls through LunaScroller with auto-scroll driving ScrollOffset (GameFull's Credits.uxml flipped to match). Only relevant if you subclassed or copied these views._CameraOpaqueTexture / Scene Color (refraction, heat distortion, glass) now opts in via UIRenderSettings.SceneColorTexture / Builder.WithSceneColorTexture(true); without the opt-in the distortion area renders black or fully transparent. The flag is re-applied per slot activation, so pooled slots never leak one content's opt-in into the next. See Scene color.AttachToPanelEvent reaching the installed root, which UI Toolkit never does, so any luna-fx element added after the view installed (a runtime-instantiated template, a code-built row) rendered bare unless you called Rescan yourself. The dead handler is gone; Carousel pages and LunaListView rows now rescan themselves on creation like GridView slots already did, and the UI Effects page documents UIEffectPanelHook.Rescan(subtree) as the one call your own runtime subtrees need.NullReferenceException from FadeUIElement.FadeIn, and TabView no longer resets to its default tab on every UXML/USS save; it reflects the already-active channel on attach.PanelSettingsThemeGuard detects destroyed ("zombie") live theme references on PanelSettings at play entry and reassigns the live theme, loudly. A genuinely stale imported theme still needs an editor restart, now documented.contentContainer. A view root that overrides contentContainer (the slot pattern) no longer captures the nav backdrop into its content area; the dim renders behind the whole view.Hide() instead of popping) is treated as a dismissal and cascades everything stacked above it closed — correct, but it used to be silent, and diagnosing "my modal goes black on first open" from that took a full bisect session. Nav now warns with the faded node's id, the number of frames closed above it, and the two right alternatives (Hidden While Open / SetRenderOccluded). See External closes.SetRenderOccluded queues through a fade-in. An occlude request during the view's entrance used to return an ambiguous false (indistinguishable from "already occluded"), forcing callers into retry loops. It now queues and applies when the fade settles, returning true; un-occluding cancels the pending request. See Occlusion.StartVisible tab is seeded onto its channel at boot so its container knows which tab to open on — correct, and deliberately not shown until the container opens. The runtime derives visibility from stack position and containment; the debugger derived it from stack position alone, and painted such a tab as the bright-green "visible top" while its container was invisible. Both now route through one predicate, and those tabs get their own next tier (bright amber) instead of folding into dormant, because "the tab that opens next" and "a tab that merely kept its state" are different facts worth telling apart at a glance.VisualElements, _instance singletons, warn-once flags and public events did exactly that. Every static in the package is now classified with Unity 6000.5's [AutoStaticsCleanup] / [NoAutoStaticsCleanup], with the analyzer enabled so an unclassified one is a compile error rather than an audit. Where the attribute cannot express the teardown — LunaSpotlight disposing its controllers, LunaTicker pausing its scheduled item — a play-mode cleanup hook does it instead of the old [RuntimeInitializeOnLoadMethod] resets.NavHost ready gate — and with it LunaLayers.AllReady and any boot loading cover — in total silence. Eight seconds after boot, a still-waiting host warns with each stuck view's renderer, parentName, and the new UIViewComponent.ReloadCount, separating "the PanelRenderer never announced a tree" from "delivered, but no view root resolved". UIViewComponent also errors loudly at Awake when no PanelRenderer resolves at all (previously silent unless _debug).PanelRenderer — and NavHost was overwriting the shell's sortingOrder once per child (and could re-trigger shell rebuilds through panel-settings reassignment). Render order and panel settings now apply only to a renderer living on the view itself.CreditsView armed its auto-scroll in OnUILoaded, and every node's view is preloaded by the NavHost, so the roll ran on a credits screen that was never opened. A hidden element has no resolved layout, so MaxScroll read 0, the "fully scrolled" branch was true on the very first tick, and the auto-close fired PopBackStack — which pops whatever is on top. In GameFull that was the main menu, about a second after boot, leaving a black screen with no error in the console. The roll now starts on OnViewShown, stops on OnViewHiding, resets its scroll offset and timers on every open, refuses to complete until the scroller has a real extent, and closes through the new PopSelf. If you subclassed CreditsView or copied its ticker pattern, move any load-time timer to the per-open pair: a preloaded view's OnUILoaded/OnEnable runs while the view is closed.UIViewComponent cached its nav backdrop element across reloads; when a UXML/USS live reload released the old tree, the released backdrop was re-inserted into the fresh tree and UITK threw InvalidOperationException once per open backdropped view. The backdrop is rebuilt whenever its tree has been torn down. Editor-time authoring annoyance only — player builds never live-reload.tooltip-right / tooltip-left card anchored to a target near the bottom of the panel used to overflow, fail every alternative, and land on Top clipped off-screen (a tall unit card on a bottom-docked hero list). Placement now keeps the requested side and slides the card along that edge first; the flip search runs only when the side itself has no room. tooltip-top / tooltip-bottom slide horizontally the same way. See Tooltip.PlayProgress / PlayIndicator / InstantAllSegments never stopped a running one, so a non-instant play followed by an instant play in the same frame (a card unbound and rebound on a list refresh) snapped to the new value and then drifted back to the stale target tick by tick. The instant path now stops that node's animation first.--luna-fx-gradient values are loud. A value that fails to parse now logs a warning naming the element instead of silently rendering nothing. Remember the value must be quoted in USS.DialogueController queried ParentElement in Awake, before any panel tree could load — a freshly instantiated view (a world-space speech bubble, a consumer-spawned tutorial modal) threw on Awake and every pre-load setter NREd. UI queries now run on the OnUILoaded contract (fires synchronously when already loaded, and on every UI reload), SpeechBubbleController's setters are state-first (configure immediately after instantiating; the state applies when the elements exist), and all three implementations hook their callbacks idempotently (-= before +=) instead of relying on paired OnEnable/OnDisable. If you subclassed a dialogue view, note that InitializeUI now runs per UI load rather than once in Awake. See Dialogue Controller.confirm destination (Save / Discard / Cancel, awaited ChoicePopupArgs); SettingsMenuView gained a _confirmDest catalog key — leave it empty to keep the old save-and-exit behavior. The screen's stale embedded ChoicePopup copy is gone.TransitionPresetGalleryDemo.uss — this also fixes cards losing their size and color after a loop iteration null-restored inline styles that had no USS values to fall back on.UIRenderHandleSet sample helper.Tag atom's circle default too).hero.detail, inventory, journeypass, mailbox, profile, chat) lists home, so the tab shell stops rendering beneath them and fades back in on close — no controller code, one field on the node. See Navigation.ScrollAlignment, RefreshItems against a growing and shrinking source vs Rebuild), Scroller (vertical feed with a nested horizontal scroller, every ScrollTo overload, live friction/wheel/scrollbar knobs) and Carousel (peek pager and shelf side by side). The Notifications entry moves its scenarios to a centered column, the DragAndDrop entry is re-pointed at its own controller (its icons had gone missing), and the GridView/Pagination demos build their data before base.Awake().LunaScroller/LunaListView; structural .unity-scroll-view__* USS moved to .luna-scroller__content/.luna-listview__row (including the gf-scroll-tight shared gutter, now on Luna thumb variables); ShopTab arrows, ChatView autoscroll and the Leaderboard sticky rows (silently dead since the GridViewList flip) are rewired to ScrollChanged/ScrollOffset/MaxScroll. Deliberately still native: JourneyPass (two-axis map), the Storybook List & ScrollView styling entry (native controls stay themeable), and SaveLoad (rides the gamesave bridge).UIRenderDemoSnapshot.unity: a 24-cell roster grid toggling between a live camera per cell and Snapshot mode, with a live readout of slots in use, pending captures and cached snapshots. The roster repeats its six characters on purpose, so the cache hits are visible.The localization-consolidation pass. Luna had grown two runtime localized-text helpers (a bare one in the localization folder, a featureful one buried in the notification component) and a customer wrote a third. All of that is now one public API with loud failure behavior. If you never touched the removed classes, there is no migration work.
TextElement.BindLocalizedText(table, entry, args, fallback) binds a label or button to a string-table entry using Unity's runtime binding, so the text re-localizes live on locale change. A LocalizedString overload covers authored references, and ClearLocalizedText() removes the binding. The extension class compiles with or without com.unity.localization: without the package (or with the key unset) the fallback text is assigned instead, so the same code runs in both states. LunaLocalization.Resolve(table, entry, args) is the synchronous companion for baking snapshots (history rows, dedup keys), and LunaLocalization.Format guards string.Format templates. Failures are loud: an unresolvable key logs a warning, a malformed template logs an error. See Runtime binding from C#."table/entry" key form on NotificationDefinition is unchanged, but a key that is set and not in that form now logs a warning instead of silently showing the fallback.NotificationLocalization: replaced by BindLocalizedText and LunaLocalization. It parsed its own key convention and swallowed every resolution error silently.LocalizedVisualElement: predated the new API, had no fallback or argument support, and its whole class vanished from the compile when com.unity.localization was absent. BindLocalizedText covers every use.The responsive-hardening release. Three classes of "the UI is the wrong size and I don't know why" are gone: a phone-shaped Game view now scales like the phone it simulates instead of rendering a tiny desktop layout, a device that misreports its dpi can no longer force a shrunken tablet layout onto a phone, and projects running with Domain Reload disabled no longer risk a dead UI manager for the whole session. Around the fixes ships a full diagnostics layer: a live readout of the entire responsive chain, a Game-view device testbed with safe-area simulation, a screenshot gallery sweep, and a pinned device-matrix test suite. No breaking changes and no migration work.
breakpoint-sm. The detector is deliberately portrait-only (a 16:9 landscape desktop window shares its aspect ratio with a portrait phone), and ForceMobile / ForceDesktop remain absolute. See the device-class callout on Responsive.md tablet layout on a phone. Genuinely low-density phones such as the iPhone SE stay density-driven, and the check also covers landscape-locked games.BreakpointChanged event could carry a dead subscriber from the previous play session; it then threw during the manager's Awake, and Unity disabled the manager component, killing scale, breakpoints, safe area, and input init until a restart. The asset now resets its event and breakpoint state at every session start, SetBreakpoint isolates each subscriber so one throwing handler can never abort the apply, and GridViewList unsubscribes from the exact settings instance it subscribed to instead of a re-lookup that was usually null at teardown.PanelRenderer rebuilds its tree (panel-settings swap at spawn, live UXML/USS reload), the fresh subtree silently lost its .bake-* underlays and .luna-fx hooks, flaky per session by ordering. Views now reinstall and rescan both effect drivers after every reload.SetUserUIScale wrote its project-global PlayerPrefs value unconditionally, so a demo slider could permanently rescale (and even re-breakpoint) every Luna scene in the project. It now takes a persist parameter (default true, source-compatible), ResetUserUIScale() clears the pref, and the Showcase shell slider is session-only.md breakpoint no longer shatters on narrow-tall viewports.LunaUIManager.DescribeResponsiveState() renders the whole chain as one string: sampled viewport and dpi, the device-class gate and why it chose that path, base × user = final scale, logical width, breakpoint plus ladder thresholds, orientation, text scale, and safe area. It backs the boot log, bug reports, and a new live Responsive State foldout on the LunaUIManager inspector with Copy and Log buttons.Tools ▸ CupkekGames ▸ Luna ▸ Responsive Gallery): sweeps the Game view through the device matrix in Play Mode and emits a markdown gallery of readouts and screenshots per case, a ready-made visual-regression artifact to review per release.Tools ▸ CupkekGames ▸ Luna ▸ Validate Responsive): lints a leftover persisted user UI scale and managers running without a settings asset; Reset User UI Scale Pref clears a stuck scale. Validate Panels now honors a LunaValidateSkip asset label for panels deliberately not driven by Luna.LunaUIScaler.Resolve; the manager only samples, and the result carries the "why" flags (FormFactorMobile, DensityRejected) consumed by the readout and the new device-matrix test suite, which pins real-world viewports (phones, tablets, phone-shaped editor views, desktop windows, Force overrides) through the production entry point.The "opens like it should" release. Two long-standing issues made opening a view feel laggy: fades never actually animated, and a pushed window could render underneath the view it was supposed to cover. Both are fixed, plus z-order between views is now fully automatic. No breaking changes and no migration work: existing prefabs and graphs just behave better.
display: none to flex flip. The result: every fade-in on a freshly shown view completed instantly, so views popped in with no animation regardless of the configured duration. FadeUIElement now interpolates opacity manually per frame through EasingUtility. Same API, same events, same delays; only the animation engine changed.NavHost assigns every spawned view's PanelRenderer.sortingOrder from the parent-first graph walk (spawn order x 10): children render above their parent, and a later-listed root renders above an earlier root's entire subtree. Sibling order is deterministic: connection order where edges exist, the graph's node-list order everywhere else — so in a flat graph, the order nodes appear in the asset is the z order. Whatever sorting order a prefab carries is overwritten at spawn, so view prefabs never need manual z bookkeeping. See the z-order callout in Scene host setup.NavNode.SortOrderOverride (default -1, meaning automatic): per-node escape hatch for the rare view that must break spawn-order stacking, such as an always-on-top debug overlay or an under-everything HUD.NavHost.SortOrderBase: per-host offset added to every view the host spawns. Use it to band multiple hosts that share one PanelSettings asset (for example scene UI 0, game-scope pause 100, global overlays 1000). Hosts with different PanelSettings assets keep layering by PanelSettings.sortingOrder as before.rounded-pill-{24..80} utility classes for true capsule shapes. UI Toolkit scales oversized radii into an ellipse instead of clamping to a capsule like CSS, so rounded-full (9999px) is correct only on square elements. The pill classes carry the half-height radius for each control height; see Border.sortingOrder values were removed since the host now assigns them.The navigation scopes release. One thing new users kept missing: nav graphs are scoped to the
NavHostthat mounts them, not global. The only runnable multi-graph example lived in GameFull, which is the heavy extra sample. 2.0.2 adds a minimal dedicated demo to the Showcase Components folder and fixes a containment error in GameFull's main-menu graph. No breaking changes.
Components/Navigation/NavigationDemo.unity in the Showcase sample): five nav graphs on five hosts with different lifetimes, in a single scene. A persistent global graph (settings), a main-menu graph, a game-session pause scope kept alive across scene swaps, and one graph per simulated scene. Scene loads are simulated by instantiating and destroying "scene" prefabs, which exercises the real mount and unmount path: NavHost registers its graph in Awake and unregisters it in OnDestroy. Every screen carries a badge naming the graph and host that own it, and dedicated buttons deliberately push ids whose graphs are not mounted, so the Console shows the scope miss (no destination for id). The chest and map popups are proper shared-panel contained children; pause and settings are own-renderer forest roots on longer-lived hosts. Companion reading: the "Scoped, not global" callout on the Navigation page.1_GameFullNavGraphSO_MainMenu still carried a mainmenu -> credits containment edge from before the panel-ownership rule, while Credits.prefab owns its own PanelRenderer. That combination is a validation error (contained children must render inside the parent's panel). The edge is removed and credits is now a forest root; the graph validates clean. Runtime behavior is unchanged because the Credits button pushes by id.The playtest hardening release. Everything real games hit in the first weeks on 2.0.0: view-load reliability under renderer rebuilds and scene handoffs, a navigation diagnostics redesign, two new components, a new Showcase sample, and a set of dependency fixes. No migration work for plain UI users; one removal if you called
NavDestinationResolver(see Breaking below).
LunaShowcase and LunaStorybook.NotificationArgs gains ImageSource (overrides the definition's icon, for portraits and other runtime images) and ExtraFeatures (appends runtime features a static definition cannot author). Definition-driven pushes can now carry everything PushRaw could, so hardcoded-copy pushes can move into the definitions catalog.LunaNavigation.GetFirstView(string id): resolve a live view instance by destination id off the merged topology.Push calls with ids that have not resolved yet are queued while boot is held and drain in order on release, instead of failing.PanelSettings normalization by NavHost) used to orphan the load callback; the view worked but never reported loaded, holding LunaLayers.AllReady false. Subsequent reloads now complete the load on the fresh root.Parent Name now logs a loud error naming the view, the destination, and the search scope, instead of retrying forever.NavHost readiness is deferred one frame out of the UI Toolkit panel-update tick, so ready-time pushes no longer mutate the live panel set mid-update.FadeUIElement never strands a fade when its tree detaches mid-start, and transitions plus navigation survive detaches during scene loads.FindObjectsSortMode overload.SetFilling restored as an IProgressBarElement extension (dropped by accident in the ProgressBar reorg).NavDestinationResolver is removed; runtime navigation goes through the LunaNavigation verbs with plain ids, and the catalog exists for validated authoring dropdowns. See Breaking below.UIViewComponent, and containment edges are checked so shared-panel children and own-renderer forest roots stay lawful.Tools > CupkekGames > Luna (Effects, Responsive, Validate Panels, Dissolve Texture Generator, Setup UIRender Layer), with sibling submenus for Graphs, Debug, and Utilities.GameScopeNodeSO is now a ResolveIdentity subclass of the package node).IDataSerializer and the gamesave 0.3.x GetFileExtension API.PanelRenderer panels rather than mocks.All bundled dependency pins are aligned to current versions in one pass. Notable changes inside them since 2.0.0:
| Package | Version | What changed |
|---|---|---|
com.cupkekgames.services | 0.1.6 | 0.1.5 (important): with Domain Reload enabled, the editor-registration bootstrap could run again in play mode and strip every runtime ScriptableObject service registration one frame after scene load; it is now guarded out of play mode. 0.1.6 moves the Service Locator debug window under Tools > CupkekGames > Debug. |
com.cupkekgames.graphs | 0.4.1 | 0.4.0 adds a runtime-debugger selected-node detail pane (IGraphRuntimeDetailSource), read-only click-selection, and Problems grouped into cross-graph and selected-graph sections; menu moved under Tools > CupkekGames > Graphs. 0.4.1 is a pin alignment. |
com.cupkekgames.singletons | 0.1.3 | DontDestroyOnLoad is applied only on root GameObjects (Unity warns and ignores it on children). |
com.cupkekgames.data | 0.3.1 | Pin alignment only. |
NavDestinationResolver is removed. The destination catalog is authoring-only. Replace NavDestinationResolver.Resolve(...) calls with the LunaNavigation verbs (Push, Close, ...) using the destination id string, and GetFirstView(id) where you need the live view instance.🚀 The UI-focused Luna. Luna is a pure UI Toolkit framework for Unity 6 — drop it in from the Asset Store, import Essentials, and you have shader-driven UI effects, node-graph navigation, live 3D-in-UI, and a fully themed component library, with every dependency bundled (no scoped registries, no
manifest.jsonedits). Migration is light if you only use Luna for UI.Requires Unity 6000.5+ (the view layer builds on Unity 6.5's
PanelRenderer). Need help? Discord (faster) or email.
VisualElement: Outer (glow / shadow), Outline, Inner shadow, Gradient, Shine, Flash, Pattern (tile), and Dissolve. One uber-shader gated by an _ActiveEffects bitmask — textureless, and zero runtime cost when disabled. See UI Effects.NavNode destinations inside NavGraphSO assets, mounted by a scene NavHost, addressed by validated CatalogKey ids. Id-first verbs on the LunaNavigation facade — Push, PushAsync<T> (awaitable, returns Task<PushResult<T>>), Push<TArgs>, ReplaceTop, PopUpTo, ClearStackAndPush, Close, SwitchChannel, PopBackStack — each with a CatalogKey overload, plus multi-host topology merge, a boot-hold queue, synchronous route guards, and a live Graph Runtime Debugger. See the navigation guide.NavNode dropdown decides what happens beneath the top view: Overlay (default), Replace, or Overlay Opaque — a render optimization where views beneath a fully-covering solid screen stop rendering (display:none) once it settles, then are restored the instant it starts hiding. Covered views stay open with bindings live, so the reveal is instant and data-fresh through any stack depth. Stress demo: Showcase/Components/Occlusion/OcclusionDemo.unity. See Occlusion.LunaUIManager.Instance.Attractor.Burst(...) call: two-stage scatter-then-home motion, pluggable arrival reactions, and per-particle sprite overrides so one burst can carry mixed item icons.ResponsiveViewStyleSwitcher applies a breakpoint USS class to every view root from one call, backed by a semantic size-token system across screens, modals, and banners, with safe-area / UI-scaler support and a responsive GridView. See Responsive.InteractionJuiceManipulator gives any element press / release / hover feel from a reusable profile asset, and components grew UXML-wired juice slots: ProgressBar fill / drain / filled / pulse-below transitions plus an Indicator Mode (damage-ghost drains, clean-tween heals), TabView tab-pop and content-in, CooldownWipe ready-flash and cooling pulse, and Tooltip show / hide TransitionSequenceAssets with a positioning overhaul (measured before the show effect plays — no more mid-animation drift). RestoreOnEnd cleanup makes every effect interrupt-safe. See Interaction Juice.PanelRenderer-based views (Unity 6.5). UIViewComponent drives a PanelRenderer (auto-fetched from the same GameObject when unset). The tree is delivered asynchronously — query elements in OnUILoaded(root) (or gate with WhenUILoaded / the UILoaded event / IsUILoaded), never in Awake / Start.PanelRendererBinder — a lightweight base for components that bind to a PanelRenderer tree without being a full view (HUD binders, tooltip hosts), with OnPanelReady / OnPanelEnable / OnPanelDisable / OnPanelReload hooks. TooltipController extends it. See UIViewComponent → PanelRendererBinder.TabView — one headless tab element. Author plain <ui:Button> children; TabView manages .tab-bar__item / .tab-bar__item--active, fires OnTabChanged(string), and acts per its Mode: Channels (routes to LunaNavigation.SwitchChannel), Panels (display-toggles local .tab-panel siblings), Events (event only), or Auto. Gamepad LB/RB cycling built in.ChoicePopupController, N buttons) and Input Popup (InputPopupController, single-line text with a Validate predicate gating Confirm): register one prefab as a nav destination, push it from anywhere with per-call args, and await the outcome — PushAsync<int> resolves the clicked choice, PushAsync<string> the confirmed text; Esc / backdrop resolve as dismissed.MaxValue once and drive it in absolute units (PlayTo(hp), SnapTo(hp), absolute current/target accessors), with RescaleMaxValue re-proportioning in place for max-HP-increase moments; linear and radial bars share one IProgressBarElement API, so every extension works on both.DelegateGridViewList<T> / DelegateGridViewPagination<T> bind a grid with makeItem / bindItem / unbindItem delegates (UI Toolkit's ListView idiom — no subclass), plus explicit column control via SetFixedItemPerLine.ElementSelector — element queries and transition targets author as a single CSS-selector string parsed by Luna's ElementQuery.Label.PlayCountTo(from, to, durationMs, format) — rolling-number animation for HUD counters, the numeric counterpart of ProgressBar.PlayTo().com.cupkekgames.luna with input, the foundation primitives, and data + graphs (which power catalog-keyed nav) bundled as dependencies. No scoped registry, no chained installs.LunaShowcase flagship shell + LunaStorybook component browser + Components scenes), and GameFull (a finished-looking F2P game shell, including a full inventory / equipment screen and a drop-table loot loop wired to UIAttractor).Tools > CupkekGames > LunaUI Panel (the single-page intro screen: one-click Essentials and Showcase imports, an "Extra: GameFull" card with a live package count, health alerts only when something is broken) auto-opens on first install and on sample import; a Package Manager window installs the optional GameFull ecosystem packages in one click; UI Effect Baker + the Luna Effects window snapshot and profile effect stacks.ItemStatChangeType → ValueDeltaType, ItemStatLine → ValueComparisonLine, ItemStatLineController → ValueComparisonLineController. See Value Comparison.Font.uss for easy revert); KeyValueDatabaseDrawer replaces the per-type KeyValueDatabaseMonoSOEditor subclasses; modal input-blocking uses pickingMode / focusable instead of SetEnabled(false) (no :disabled styling flash while a modal fades).PanelRenderer and custom-filter pipeline. Older editors are blocked at install with a clear version message rather than confusing compile errors.Luna 2.x is a UI-focused re-architecture. If you used Luna only for UI, migration is light; the big-ticket changes:
UIDocument with PanelRenderer on view GameObjects (Unity's API updater won't do it for you), and move element queries from Awake / Start into OnUILoaded(root).NavGraphSO with a NavNode per destination, add a scene NavHost, and remove the old per-view Nav Destination Id wiring — the host mounts the views now. Reference destinations as [CatalogKeyConstraint(NavConstants.NavDestinationCatalogId)] CatalogKey.UIAttractorManager.Instance.X → LunaUIManager.Instance.Attractor.X (delete the manager GameObject); page input-blocking renamed to SetInputBlocked* (the bool meaning is inverted). FadeOutThenDestroy / _addDefaultEscapeAction dismissal → LunaNavigation.PopBackStack().UIViewTransitionEntry targets via an ElementSelector (CSS string) + StepMs — re-author entries that targeted by ElementName, and any ElementSelectors saved in the old structured shape.Assets/Samples/LunaUI and re-import Essentials / Showcase / GameFull; rewrite UXML/USS url() paths that pointed at the old Samples~/Library/... or LunaUI/... sample folders.The wider CupkekGames ecosystem shipped a coordinated v0.2.0 wave alongside Luna 2.0 — foundation split, kind-driven primitives, feature composition, catalog architecture, combat refactor. Only relevant if you use GameFull or pull sibling packages into your project.
Render 3D content (particles, models, VFX) directly onto UI elements using a pooled Camera → RenderTexture pipeline. Supports multiple content modes: prefab instantiation, borrowing scene objects, or observing in-place. Includes PlayOverlay for layering effects on existing UI.
See documentation: UI Render
Reusable UI animations via ScriptableObjects or code. Includes TransitionAnimator component, 52 preset animations, and UIView fade event integration.
IMPORTANT: You need to re-import the library sample to get the presets.
See documentation: Transition Animation
Time.timeScaleOnSegmentAnimationComplete, OnIndicatorAnimationCompletePlayMultiPass() for multiple 0→100% cycles (e.g., XP leveling)See documentation: Progress Bar | Radial Progress Bar
IsFading, IsFadingIn, IsFadingOut state trackingsize-* utility classes. See Size UtilitiesCelledProgressBar component has been removed. Use ProgressBar with gap line overlays instead, which provides equivalent functionality with simpler implementation.disabled state. When disabled, any active tooltips are closed and new ones are prevented from opening. Usage: TooltipController.Tooltip.SetTooltipEnabled(bool)AddTooltipReference(Tooltip) to DragAndDropManipulator. Registered tooltips are automatically disabled when a drag starts and re-enabled when the drag ends.FadeableAction enum and lifecycle action fields (OnAwake, OnEnable, OnDisable, OnDestroy). Each field accepts a FadeableAction value: None, FadeIn, FadeOut, SetFadedIn, or SetFadedOut. For example, set OnAwake to SetFadedOut and OnEnable to FadeIn to have a view start hidden and fade in each time it's enabled.aspect-ratio utility classes (aspect-auto, aspect-square, aspect-video, aspect-1-1, aspect-2-1, aspect-3-2, aspect-4-3, aspect-16-9, etc.).gap-line-count: Number of cells (gap lines = count - 1)minor-cells-per-major: Number of minor cells per major segmentminor-gap-line-width, minor-gap-line-color, minor-gap-line-rangemajor-gap-line-width, major-gap-line-color, major-gap-line-rangeminor-gap-line-min-spacing: Auto-skips minor lines when cells get too narrowSpeechBubblePositionConfig that caused build errors.All progress segments, indicators, and cells scale proportionally within the configured arc.
UpdateProgressSegments(): Simply set Progress[index].TargetValue directly and call PlayProgress().Linear progress bar with discrete cell segments for Overwatch-style health bars. Features cell-based rendering, multi-segment support, angled cells, and damage indicators.
See documentation: Celled Progress Bar
Progress array with CurrentValue, TargetValue, and Color per segmentNew structure: Linear, Radial, Celled, RPG Demo, Architecture
progress attribute from UXMLAddClassToAllUIViews() and RemoveClassFromAllUIViews() to LunaUIManager. Classes are automatically applied to existing and future UIViews.locale-en, locale-ja) to all UIView roots at runtime. Works around Unity's limitation of not being able to change global USS variables at runtime.UIView now implements IDisposable for explicit cleanup.LocalizationViewStyleSwitcher example implemented for Japanese locale only—switching to Japanese changes the font using locale-specific USS classes. You can extend this pattern to other locales as needed."onetime" to OneTime instead of PingPong. Movement effects now animate forward then return to neutral position and stay there. Refactored duplicate code with shared helper methods.https://www.docs.cupkek.games/luna/features/texteffects
Leveraging Unity 6.3's new TextElement.PostProcessTextVertices API to enable rich text animations directly on glyph vertices. This system supports 12 customizable text effects via rich text tags:
All effects support customizable parameters (speed, amplitude, intensity, etc.) through rich text tag attributes.
Visual Novel Controller: Added new VertexReveal text animation mode for smooth character-by-character reveal using vertex manipulation.
TextEffectComponent: New component to easily apply text effects without dialogue controller.
InventoryItemReferenceDrawer.txt, a sample PropertyDrawer for InventoryItemReference. It displays the int ItemType field as a custom ItemType enum dropdown in the Inspector. Provided as a .txt file to avoid conflicts if you add a custom drawer to your project.LunaUIManager.GetInputAction("Move") is now InputDeviceManager.PlayerInputs[0].actions["Move"];InputDeviceManager.PlayerInput.actions["Move"]; is now ``InputDeviceManager.PlayerInputs[0].actions["Move"];`bool IndicatorAutoColor attribute. Useful when you don't want indicator color to update automatically, for example when using SetFilling function to show a change._enableAutosave and _autosaveSlots to protected from private.If you're using GridView or Inventory, refactor is required. See details below.
Custom USS Property
Custom USS Property section in https://www.docs.cupkek.games/luna/components/progressbarCustom USS Property section in https://www.docs.cupkek.games/luna/components/radialprogressbarIf you’d like to see USS variables for other components or properties, let me know!
Samples
Samples
Warning: It's recommended to remove Luna and samples before updating. This update includes significant refactors to the Tooltip, Save/Load and Inventory systems. If you are using these features, you may need to update your implementation. Feel free to ask for support.
Tooltip System
UpdateDisplay function to TooltipManipulator for seamless tooltip updates without closing and reopening.Close function to TooltipManipulator, ensuring only the currently active tooltip is closed.DefaultTooltip has been renamed to TooltipController. Since this is a MonoBehaviour, you’ll need to update your GameObject. Select the GameObject that previously contained DefaultTooltip in your scene, remove the missing component, and add TooltipController manually.DefaultTooltipContainerSetup has been renamed to TooltipContainerSetup.DefaultTooltipManipulator has been renamed to TooltipManipulator.Save/Load System
Other
Library Sample. The inventory system is not strictly a UI component but rather a gameplay feature, making it more appropriate for Library Sample rather than the UI library. It now has it's own assembly file called CupkekGames.InventorySystem.Added:
Added:
Added:
Added:
InputEscapeManager.SetBlocked(true) but it will block all escape actions. With this new class, you can add the pause menu action to the end of the stack so that the pause menu remains accessible while blocking other back actions.New:
New:
New:
New:
Settings
Theme
Light
Contrast
Material
Dark
Dim
Material Dark
System
Sidebar(Light & Contrast only)
Font Family
DM Sans
Wix
Inclusive Sans
AR One Sans
Direction