Visual Components Guide¶
TL;DR — Why Use These¶
- AnimatedSpriteLayer: Data structure for packaging sprite animation frames with per-frame offsets and transparency
- LayeredImage: UI Toolkit element that composites multiple sprite animation layers into a single animated image
- EnhancedImage: Extended Unity UI Image with HDR color support and shape masking
These components solve the problem of creating complex, multi-layer sprite animations without pre-rendering every combination into massive sprite sheets.
AnimatedSpriteLayer¶
What it is: An immutable data structure (struct) that packages a sprite animation sequence with per-frame position offsets and layer-wide alpha transparency.
Why it exists: When building complex sprite animations (like a character with equipment, effects, or layered body parts), you need a standardized way to represent each layer with its timing, positioning, and transparency. This struct is the building block for the LayeredImage composition system.
Problem it solves:
- Eliminates manually syncing sprite frames, offsets, and alpha values across multiple systems
- Provides type-safe storage for animation layer data
- Automatically converts world-space offsets to pixel-space for rendering
- Validates texture readability at construction time (catches import setting errors early)
When to Use¶
✅ Use when:
- Building
LayeredImagecompositions - Creating character animations with separate layers for body parts
- Combining sprite effects (glow, shadow, outline) with base sprites
- You need frame-by-frame position adjustments (bobbing, recoil, etc.)
- Working with sprite-based animations that need dynamic layering
❌ Don't use when:
- You only have a single sprite sequence (just use
Animator) - Sprites don't need per-frame offsets (just use sprite arrays)
- You're working with UI Toolkit animations (use USS transitions)
- Performance is critical and you can pre-render combinations
Basic Usage¶
Editor-Only: Creating from AnimationClip¶
In editor code, you can create layers directly from AnimationClips:
| C# | |
|---|---|
Important Notes¶
Texture Readability: All sprites must have Read/Write Enabled in their texture import settings. The constructor validates this and logs errors for non-readable textures.
To fix:
- Select the texture asset
- In Inspector, check "Read/Write Enabled"
- Click Apply
Frame Rate: Default frame rate is 12 fps (stored in AnimatedSpriteLayer.FrameRate constant). This matches classic sprite animation timing.
Offset Conversion: World-space offsets are automatically converted to pixel-space using sprite pixels-per-unit. This ensures offsets scale correctly with sprite resolution.
LayeredImage¶
What it is: A UI Toolkit VisualElement that composites multiple AnimatedSpriteLayer instances into a single animated image with alpha blending, automatic cropping, and frame timing.
Why it exists: Creating character customization systems (body + equipment), visual effects (base + glow), or any multi-layer sprite animation traditionally requires pre-rendering every combination into massive sprite sheets. LayeredImage composes layers dynamically at runtime.
Problem it solves:
- Sprite sheet explosion: Instead of 10 bodies × 20 helmets × 15 armors = 3,000 pre-rendered sprites, you have 10 + 20 + 15 = 45 source sprites
- Memory efficiency: Only active layers are loaded, not every possible combination
- Runtime flexibility: Change equipment/effects without new assets
- Automatic composition: Handles alpha blending, pivot alignment, and cropping
When to Use¶
✅ Use when:
- Character customization systems (swap equipment, clothing, accessories)
- Visual effects that layer over base sprites (shields, auras, damage flashes)
- Procedural sprite generation from components
- UI that needs animated, multi-layer sprites
- You want to avoid combinatorial explosion of pre-rendered sprites
❌ Don't use when:
- Single-layer animations (use Unity's
ImageorAnimator) - 3D models (use skinned mesh renderers)
- Performance is absolutely critical and you can afford pre-rendered sheets
- Sprites don't share the same frame count/timing
- Working in UGUI (use
EnhancedImagefor UGUI, though it doesn't support layering)
Basic Usage¶
Manual Frame Control¶
If you need precise control over frame advancement:
Changing Animation Speed¶
| C# | |
|---|---|
Visual Demo¶
LayeredImage in Action
Character with dynamically composited layers animating at runtime
Swapping equipment layers at runtime without pre-rendered sprite sheets
How Compositing Works¶
LayeredImage performs these steps each frame:
- Allocates canvas: Creates a texture large enough to hold all layers with their offsets
- Alpha blending: Layers are composited back-to-front with alpha blending
- Pivot alignment: Each sprite's pivot point is respected during positioning
- Offset application: Per-frame pixel offsets are applied
- Cropping: Transparent borders are trimmed (configurable via
pixelCutoff) - Rendering: Final composited texture is displayed
Performance optimization:
- Uses parallel processing for large sprites (2048+ pixels total)
- Employs array pooling to minimize GC allocations
- Caches composited frames when possible
Pixel Cutoff Parameter¶
Controls how aggressive transparent pixel cropping is:
| C# | |
|---|---|
Higher values = smaller final image, but may clip soft edges (glows, shadows).
Important Notes¶
Frame Synchronization: All layers must have the same number of frames. Mixing 4-frame and 8-frame animations will cause visual glitches.
Performance Considerations:
- Compositing happens every frame for animated images
- Large sprite resolutions (1024×1024+) will impact performance
- Consider pre-rendering if targeting low-end devices
- Parallel processing threshold is 2048 pixels (width × height)
Editor vs Runtime:
- In Editor: Uses Unity's editor update ticks for animation
- In Runtime: Uses coroutines for frame timing
- Both honor
updatesSelfsetting
EnhancedImage (UGUI)¶
What it is: An extended version of Unity's UI Image component with HDR color support and texture-based shape masking.
Why it exists: Unity's standard Image component doesn't support:
- HDR colors (for bloom/glow effects)
- Complex shape masks (beyond sprite masks)
- Shader-based shape rendering
See full documentation: Editor Tools Guide - EnhancedImage
Visual Demo
HDR color values above 1.0 create bloom effects when post-processing is enabled
Quick example:
| C# | |
|---|---|
Best Practices¶
AnimatedSpriteLayer¶
- Always enable Read/Write on source textures (build will fail otherwise)
- Keep frame counts consistent across layers for the same animation
- Use world-space offsets for consistent motion across different sprite resolutions
- Cache layer instances when using the same animation repeatedly (they're immutable)
LayeredImage¶
- Layer order matters: Layers are rendered front-to-back in array order
- Optimize sprite sizes: Trim transparent borders before importing (use Sprite Editor's "Tight" mode)
- Profile on target hardware: Mobile devices may struggle with 512×512+ composites at 60fps
- Use manual updates when syncing with non-UI systems (like gameplay state)
- Pre-render if combinations are limited and performance is critical
EnhancedImage¶
- Don't mix with Image: EnhancedImage replaces Unity's Image, don't use both
- Material cleanup is automatic but test in edit mode transitions
- HDR requires post-processing: Ensure Bloom is enabled in your camera's post-processing
Related Documentation¶
- Editor Tools Guide - EnhancedImage editor integration
- Samples - Example projects in
Samples~folder in the repository - Math & Extensions - Color utilities used internally
FAQ¶
Q: Can I mix different frame counts in LayeredImage? A: No, all layers must have the same frame count. Pad shorter animations with duplicate frames if needed.
Q: Why are my layers not aligned correctly? A: Check that sprite pivots are set correctly (usually center). LayeredImage respects sprite pivot points.
Q: Can I change layers at runtime? A: Currently no, LayeredImage is immutable after construction. Create a new instance with updated layers.
Q: Performance impact vs pre-rendered sprites? A: Compositing costs ~1-3ms per image on modern hardware. Pre-rendered is faster but uses more memory/storage.
Q: Does this work with Unity's Animator? A: No, LayeredImage is independent. It's designed for UI Toolkit programmatic control.
Q: Can I export the composited result? A: Not directly, but you could capture the rendered texture using Texture2D.ReadPixels in a render texture setup.


