Luna provides a powerful Transition Animation system for creating smooth, reusable UI animations using UI Toolkit's CSS transitions. Build complex animation sequences declaratively via ScriptableObjects or programmatically with a fluent API.

The simplest way to add animations is through the TransitionAnimator component:
TransitionAnimator to a GameObjectUIDocument or UIViewComponent// Play animation manually
transitionAnimator.Play();
// Or enable "Play On Enable" in the InspectorLuna includes 52 preset animation assets. Simply reference them in the TransitionAnimator:
// Load and play a preset directly
TransitionSequenceAsset fadeIn = Resources.Load<TransitionSequenceAsset>("TransitionPresets/Base/FadeIn");
var player = fadeIn.CreatePlayer();
player.Play(myElement);Build animations programmatically with the TransitionSequence builder:
var sequence = new TransitionSequence()
.Opacity(0f, 0.3f, EasingMode.EaseOut) // Fade out
.Scale(0.8f, 0.3f, EasingMode.EaseOut) // Scale down
.Build();
var player = new TransitionSequencePlayer(sequence);
player.OnComplete += () => Debug.Log("Animation complete!");
player.Play(myElement);MonoBehaviour that plays transition animations on VisualElements.
| Property | Description |
|---|---|
| Nodes | Ordered list of animation nodes (inline step groups or sub-sequence asset references) |
| Play Mode | Once, Loop, PingPong, or LoopCount |
| Loop Count | Number of loops when Play Mode is LoopCount |
| UI View Component | Optional UIViewComponent reference for target resolution |
| UI Document | UIDocument reference (used when no UIViewComponent is set) |
| Element Name | Name of the target VisualElement (leave empty for root) |
| Fade Trigger | Which UIView fade event triggers this animation |
| Play On Enable | Automatically play when the component is enabled |
// Play the animation on the configured element
public void Play()
// Play on a specific element
public void Play(VisualElement target)
// Stop playback
public void Stop()
// Pause/Resume
public void Pause()
public void Resume()
// Create a sequence or player from this animator's nodes
public TransitionSequence CreateSequence()
public TransitionSequencePlayer CreatePlayer()UnityEvent OnComplete; // Fired when animation completes
UnityEvent OnStopped; // Fired when animation is stoppedScriptableObject for defining reusable animation sequences. Create via: Create > CupkekGames > Luna > Transition Sequence
Supports:
Runtime player for executing transition sequences on a VisualElement.
// Create from a built sequence
var player = new TransitionSequencePlayer(sequence);
// Or from an asset
var player = myAsset.CreatePlayer();
// Enable debug logging
player.Debug = true;
// Play on target
player.Play(myElement);
// Check state
bool isPlaying = player.IsPlaying;
bool isPaused = player.IsPaused;
int currentNode = player.CurrentNodeIndex;
int currentIteration = player.CurrentIteration;event Action OnComplete; // Sequence fully complete
event Action<int> OnIterationComplete; // After each loop pass
event Action OnStopped; // Playback stopped via Stop()The TransitionSequence class provides a fluent API for building animations:
var sequence = new TransitionSequence()
// Opacity
.Opacity(1f, 0.3f)
.Opacity(0f, 0.3f, EasingMode.EaseOut)
// Scale (uniform or separate x/y)
.Scale(1.2f, 0.2f)
.Scale(new Vector2(1.5f, 1f), new TransitionTimingConfig(0.3f, EasingMode.EaseInOut))
// Translate (pixels or percent)
.Translate(0f, -20f, 0.3f)
.TranslatePercent(0f, -50f, 0.3f)
// Rotate (degrees)
.Rotate(360f, 0.5f)
// Colors
.BackgroundColor(Color.red, 0.2f)
.Color(Color.blue, StyleColorProperty.BorderColor, new TransitionTimingConfig(0.2f))
// Length properties
.Width(new Length(200, LengthUnit.Pixel), new TransitionTimingConfig(0.3f))
.Height(new Length(50, LengthUnit.Percent), new TransitionTimingConfig(0.3f))
.Build();Run multiple animations simultaneously:
var sequence = new TransitionSequence()
.Together(sub => sub
.Opacity(1f, 0.3f)
.Scale(1f, 0.3f)
.Translate(0f, 0f, 0.3f)
)
.Build();var sequence = new TransitionSequence()
.Opacity(0f, 0.3f)
.Delay(0.5f) // Wait 500ms
.Callback(() => Debug.Log("Halfway done!"))
.Opacity(1f, 0.3f)
.Build();var sequence = new TransitionSequence()
.Scale(1.1f, 0.2f)
.Scale(1f, 0.2f)
.WithPlayMode(TransitionPlayMode.Loop) // Loop forever
.Build();
// Or loop a specific number of times
var sequence = new TransitionSequence()
.Rotate(360f, 1f)
.WithPlayMode(TransitionPlayMode.LoopCount)
.WithLoopCount(3) // Rotate 3 times
.Build();Animate multiple properties with shared timing:
var timing = new TransitionTimingConfig(0.3f, EasingMode.EaseOutBack);
var sequence = new TransitionSequence()
.Multi(timing,
new OpacitySetter(1f),
new ScaleSetter(new Vector2(1f, 1f)),
new TranslateSetter(Translate.None())
)
.Build();Luna includes 52 ready-to-use animation presets organized into categories:
| Preset | Description |
|---|---|
| FadeIn / FadeOut | Opacity transitions |
| ScaleIn / ScaleOut | Scale from/to zero |
| SlideInUp/Down/Left/Right | Slide from off-screen |
| SlideOutUp/Down/Left/Right | Slide to off-screen |
| FlipIn / FlipOut | 3D flip effect via scaleX |
| RotateIn / RotateOut | Rotation with opacity |
| BounceIn | Bouncy scale entrance |
| Preset | Description |
|---|---|
| Shake / ShakeVertical | Horizontal/vertical shaking |
| Wobble | Rotation wobble |
| Jello | Elastic jiggle effect |
| Rubber | Rubber band stretch |
| Flash | Rapid opacity flashes |
| Heartbeat | Pulsing scale |
| ColorPulse | Background color pulse |
| Preset | Description |
|---|---|
| Pop | Quick scale bump |
| PopBounceIn / PopBounceOut | Bouncy pop entrance/exit |
| Press | Button press effect |
| Lift / LiftReset | Hover lift effect |
| Squish | Squash and stretch |
| Preset | Description |
|---|---|
| Spin | Continuous rotation |
| Bounce | Vertical bounce |
| Blink | Opacity blink |
| Breathe | Gentle scale pulse |
| Preset | Description |
|---|---|
| ZoomIn / ZoomOut | Scale with opacity |
| RiseIn / RiseOut | Rise from bottom |
| DropIn | Drop from top with bounce |
| SwingIn / SwingOut | Rotation swing |
| FoldY / UnfoldY | Vertical fold effect |
| Preset | Description |
|---|---|
| SlideInTop / SlideInBottom | Notification slide in |
| SlideOutTop / SlideOutBottom | Notification slide out |
| Preset | Description |
|---|---|
| PushInLeft / PushInRight | Page push entrance |
| PushOutLeft / PushOutRight | Page push exit |
UIViews can automatically play transition animations on fade events. See UIView Transitions for details.
// Add transition to UIView
myUIView.AddTransition(new UIViewTransitionEntry
{
Animation = popBounceInAsset,
Trigger = FadeEventTrigger.FadeInStart,
ElementName = "modal-content"
});Encapsulates timing configuration for transitions:
var timing = new TransitionTimingConfig(
duration: 0.3f, // Duration in seconds
easing: EasingMode.EaseOut, // Easing function
delay: 0.1f // Delay before start
);All Unity UI Toolkit easing modes are supported:
LinearEase, EaseIn, EaseOut, EaseInOutEaseInSine, EaseOutSine, EaseInOutSineEaseInQuad, EaseOutQuad, EaseInOutQuadEaseInCubic, EaseOutCubic, EaseInOutCubicEaseInCirc, EaseOutCirc, EaseInOutCircEaseInElastic, EaseOutElastic, EaseInOutElasticEaseInBack, EaseOutBack, EaseInOutBackEaseInBounce, EaseOutBounce, EaseInOutBouncepublic class ButtonHoverEffect : MonoBehaviour
{
[SerializeField] private TransitionSequenceAsset _hoverIn;
[SerializeField] private TransitionSequenceAsset _hoverOut;
private UIDocument _doc;
private TransitionSequencePlayer _playerIn;
private TransitionSequencePlayer _playerOut;
private VisualElement _button;
void Start()
{
_doc = GetComponent<UIDocument>();
_button = _doc.rootVisualElement.Q<Button>("my-button");
_playerIn = _hoverIn.CreatePlayer();
_playerOut = _hoverOut.CreatePlayer();
_button.RegisterCallback<PointerEnterEvent>(e =>
{
_playerOut.Stop();
_playerIn.Play(_button);
});
_button.RegisterCallback<PointerLeaveEvent>(e =>
{
_playerIn.Stop();
_playerOut.Play(_button);
});
}
}// Create a continuous spinning animation
var spinSequence = new TransitionSequence()
.Rotate(360f, 1f, EasingMode.Linear)
.WithPlayMode(TransitionPlayMode.Loop)
.Build();
var spinner = new TransitionSequencePlayer(spinSequence);
spinner.Play(loadingIcon);
// Stop when loading completes
spinner.Stop();The Components sample includes three demo scenes:
Import the Components sample to explore these demos.
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