#bevy-animation #animation #aseprite #loader #bevy #atlas

bevy_aseprite_ultra

A Bevy plugin for directly loading spritesheets and animations from aseprite binary files with hot reloading support

16 releases (5 breaking)

0.6.1 May 12, 2025
0.5.0 Apr 25, 2025
0.4.1 Dec 11, 2024
0.3.0 Nov 30, 2024
0.2.3 Jul 26, 2024

#137 in Game dev

Download history 90/week @ 2025-01-29 170/week @ 2025-02-05 157/week @ 2025-02-12 108/week @ 2025-02-19 150/week @ 2025-02-26 63/week @ 2025-03-05 85/week @ 2025-03-12 36/week @ 2025-03-19 52/week @ 2025-03-26 40/week @ 2025-04-02 59/week @ 2025-04-09 64/week @ 2025-04-16 207/week @ 2025-04-23 72/week @ 2025-04-30 320/week @ 2025-05-07 128/week @ 2025-05-14

735 downloads per month

MIT license

1.5MB
979 lines

Bevy Aseprite Ultra

License: MIT or Apache 2.0 Crate

The ultimate bevy aseprite plugin. This plugin allows you to import aseprite files into bevy, with 100% unbreakable hot reloading. You can also import static sprites from an aseprite atlas type file using slices with functional pivot offsets!

Bevy Version Plugin Version
0.16 0.6.1
0.15 0.4.1
0.14 0.2.4
0.13 0.1.0

Supported aseprite features

  • Animations
  • Tags
  • Frame duration, repeat, and animation direction
  • Layer visibility
  • Blend modes
  • Static slices and pivot offsets

Features in bevy

  • Hot reload anything, anytime, anywhere!
  • Full control over animations using Components.
  • One shot animations and events when they finish.
  • Static sprites with slices. Use aseprite for all your icon and UI needs!
  • Render to custom material and write shaders ontop.
  • Asset processor which converts the aseprite file to a custom format.

(hot reloading requires the file_watcher feature in bevy)

Examples

cargo run --example slices
cargo run --example animations
cargo run --example ui
cargo run --example asset_processing --features asset_processing
cargo run --example 3d --features 3d

Example

character animation by Benjamin


use bevy::prelude::*;
use bevy_aseprite_ultra::prelude::*;

...

// Load an animation from an aseprite file
fn spawn_demo_animation(mut cmd : Commands, server : Res<Assetserver>){
    cmd.spawn((
        AseAnimation {
            aseprite: server.load("player.aseprite"),
            animation: Animation::tag("walk-right")
                .with_repeat(AnimationRepeat::Count(1))
                .with_speed(2.)
                // Aseprite provides a repeat config per tag, which is beeing ignored on purpose.
                .with_repeat(AnimationRepeat::Count(42))
                // The direction is provided by the asperite config for the tag, but can be overwritten.
                .with_direction(AnimationDirection::PingPong)
                // you can also chain finite animations, loop animations will never finish
                .with_then("walk-left", AnimationRepeat::Count(4))
                .with_then("walk-up", AnimationRepeat::Loop),
        },
        // The Render target. There are default impls for Sprite, Ui and 3D.
        // You may also define your own. Checkout the examples.
        Sprite {
            flip_x: true,
            ..default()
        },
    ));
}

// Load a static slice from an aseprite file
// create for any static atlas with marked regions aka slices.
fn spawn_demo_static_slice(mut cmd : Commands, server : Res<Assetserver>){
    cmd.spawn((
        AseSlice {
            name: "ghost_red".into(),
            aseprite: server.load("ball.aseprite"),
        },
        Sprite::default(),
    ));
}

// animation events
// this is useful for one shot animations like explosions
fn despawn_on_finish(mut events: EventReader<AnimationEvents>, mut cmd : Commands){
    for event in events.read() {
        match event {
            AnimationEvents::Finished(entity) => cmd.entity(*entity).despawn_recursive(),
            // you can also listen for loop cycle repeats
            AnimationEvents::LoopCycleFinished(_entity) => (),
        };
    }
}

Bevy Ui

Nothing to changes. Just add the animation/slice together with an ImageNode.

// animations in bevy ui
cmd.spawn((
        Button,
        ImageNode::default(), // RenderTarget
        AseAnimation {
            aseprite: server.load("player.aseprite"),
            animation: Animation::tag("walk-right"),
        },
));

// slices in bevy ui
cmd.spawn((
        Node {
            width: Val::Px(100.),
            height: Val::Px(100.),
            border: UiRect::all(Val::Px(5.)),
            ..default()
        },
        ImageNode::default(), // RenderTarget
        AseSlice {
            name: "ghost_red".into(),
            aseprite: server.load("ghost_slices.aseprite"),
        },
));

Enable Asset Processing

Simply enable asset processing in your AssetPlugin like so:

App::new()
    .add_plugins(DefaultPlugins.set(AssetPlugin {
        mode: AssetMode::Processed,
        ..Default::default(),
    }))
    .run();

Then run with the feature asset_processing enabled, e.g.:

cargo run --features asset_processing

Then load your aseprite files in code as usual!

Dependencies

~60–98MB
~1.5M SLoC