OrbitView (luna:OrbitView) is a RenderElement
subclass that turns a 3D render into a turntable viewer: drag to rotate, flick for
inertia, and an idle auto-orbit that resumes after release. It orbits the slot
camera around the content on a fixed pivot; the content itself is never rotated,
so live content (animated characters, particles, physics) keeps playing untouched.
The element owns the whole viewer presentation through UXML attributes, so the code
side is a plain Play(prefab) with no settings object.
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:luna="CupkekGames.Luna">
<luna:OrbitView name="WeaponView"
render-width="768" render-height="480"
frame-padding="1.35" frame-reference-extent="0.5"
initial-yaw="30" initial-pitch="12"
idle-orbit-speed="16" idle-resume-delay="1.5"
pitch-min="-15" pitch-max="45"
style="width: 100%; flex-grow: 1;" />
</ui:UXML>OrbitView view = root.Q<OrbitView>("WeaponView");
view.Play(weaponPrefab); // element bakes framing, AA and orbit into the settings
view.Play(otherWeaponPrefab); // swap: continues from the current orbit angle
view.SetOrbit(yaw: 90f, pitch: 0f); // explicit jump, kills inertiaScene setup is the same as the rest of UI Render (a UIRenderManager, a
LunaUIManager, and a dedicated layer); see the
UI Render Quick Start.
pitch-min..pitch-max.inertia-damping.idle-orbit-speed degrees per second once
idle-resume-delay seconds pass without input. Set the speed to 0 to disable.initial-yaw / initial-pitch. Every re-play, item
swaps included, continues seamlessly from wherever the orbit currently is: the
element bakes its current angles into the camera rotation before the slot
activates, so there is no first-frame snap.SetOrbit(yaw, pitch) jumps to an explicit angle and kills inertia. Calling it
right after Play overrides the initial-angle snap.Current angles are readable via the Yaw and Pitch properties.
On top of the inherited render-width / render-height:
| Attribute | Default | Description |
|---|---|---|
drag-sensitivity | 0.4 | Degrees of rotation per pixel of drag. |
idle-orbit-speed | 12 | Auto-orbit speed in degrees per second. 0 disables the idle orbit. |
idle-resume-delay | 1.5 | Seconds after release before the idle orbit resumes. |
inertia-damping | 4 | Exponential decay rate of flick inertia. Higher stops sooner. |
pitch-min / pitch-max | -15 / 45 | Camera pitch clamp in degrees. |
initial-yaw / initial-pitch | 30 / 12 | Orbit angles for the first play. |
auto-frame | true | Frame the camera to the content bounds. |
frame-padding | 1.2 | Auto-frame padding (1.0 = tight). |
frame-reference-extent | 0 | Frame for this fixed extent instead of each content's own bounds; see below. 0 frames per content. |
anti-aliasing | 4 | MSAA sample count for the slot's RenderTexture. |
preserve-content-rotation | true | Keep the prefab's authored rotation instead of resetting it to identity. |
These attributes are baked into the UIRenderSettings by the element itself
(ResolveSettings is virtual on RenderElement), so a caller-supplied settings
object passes through for everything else (resolution overrides, background color,
HDR, and so on) while the viewer presentation stays element-owned.
By default auto-framing fits each content's own bounds, so a knife and a rifle both
fill the frame at the same apparent size. Setting frame-reference-extent frames
the camera for that fixed extent (in world units) instead: every item shown through
the same element shares one frustum, so the knife reads smaller than the rifle. Pick
the extent near the largest item's half-size, then tune frame-padding for breathing
room.
Play normally spawns prefab copies at identity rotation. OrbitView defaults
preserve-content-rotation to true, so the model keeps its authored facing and
initial-yaw is relative to that. Disable it if your prefabs are authored at
arbitrary rotations and you want a normalized start.
The Showcase sample's EsportLobby experience uses OrbitView twice:
frame-reference-extent="0.5", so switching operatives keeps the weapons at true
relative scale.InitialYaw / InitialPitch from demo data before each Play; the swap
continues from the current orbit, so browsing the track feels continuous.WithFrameReferenceExtent and the rest of the builder API.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