#hot-reloading #aseprite #animation #bevy #bevy-plugin #bevy-ui #atlas

bevy_aseprite_ultra

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

7 releases

0.2.4 Aug 2, 2024
0.2.3 Jul 26, 2024
0.1.1 May 13, 2024
0.1.0 Apr 22, 2024

#749 in Game dev

Download history 189/week @ 2024-07-29 22/week @ 2024-08-05 1/week @ 2024-08-12 27/week @ 2024-08-19 6/week @ 2024-09-02 2/week @ 2024-09-09 21/week @ 2024-09-16 51/week @ 2024-09-23 38/week @ 2024-09-30 9/week @ 2024-10-07 21/week @ 2024-10-14 4/week @ 2024-10-21 17/week @ 2024-10-28 31/week @ 2024-11-04 2/week @ 2024-11-11

56 downloads per month

MIT license

1.5MB
697 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.14 0.2.4
0.13 0.1.0

I use it in my game, check it out on my blog

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!

(for hotreload to work, you must have the file_watcher cargo dependency for bevy installed)

Example

cargo run --example slices
cargo run --example animations

Example

character animation by Benjamin


There are two main Bundles added by this plugin, AsepriteAnimationBundle and AsepriteSliceBundle.

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

...

// Load the an animation from an aseprite file
fn spawn_demo_animation(mut cmd : Commands, server : Res<Assetserver>){
    cmd.spawn(AsepriteAnimationBundle {
        aseprite: server.load("player.aseprite"),
        transform: Transform::from_translation(Vec3::new(15., -20., 0.)),
        animation: Animation::default()
                .with_tag("walk-right")
                .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
                // after the animation is loaded.
                .with_direction(AnimationDirection::PingPong)
                // you can also chain finite animations, loop animations with never finish
                .with_then("walk-left", AnimationRepeat::Count(4))
                .with_then("walk-up", AnimationRepeat::Loop)
        // you can override the default sprite settings here
        sprite: Sprite {
            flip_x: true,
            ..default()
        },
        ..default()
    });
}

// Load a static slice from an aseprite file
fn spawn_demo_static_slice(mut cmd : Commands, server : Res<Assetserver>){
    cmd.spawn(AsepriteSliceBundle {
        slice: "ghost_blue".into(),
        // you can override the default sprite settings here
        // the `rect` will be overriden by the slice
        // if there is a pivot provided in the aseprite slice, the `anchor` will be overwritten
        // and changes the origin of rotation.
        sprite: Sprite {
            flip_x: true,
            ..default()
        },
        aseprite: server.load("ghost_slices.aseprite"),
        transform: Transform::from_translation(Vec3::new(32., 0., 0.)),
        ..default()
    });
}

// animation events - tell me when the animation is done
// 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

There is also an Ui Bundle for Bevy Ui Nodes!

// animations in bevy ui
cmd.spawn((
        ButtonBundle{
            // node config
            ..default()
        },
        AsepriteAnimationUiBundle{
            aseprite: server.load("yourfile.aseprite"),
            animation: Animation{
                tag : Some("idle".to_string()),
                ..default()
            },
            ..default()
        },
));

// slices in bevy ui
cmd.spawn((
        ImageBundle{
            // node config
            ..default()
        },
        AsepriteSliceUiBundle{
            aseprite: server.load("yourfile.aseprite"),
            slice: AsepriteSlice::from("your_slice"),
            ..default()
        },
));

Dependencies

~41–79MB
~1.5M SLoC